Some svn up ago, Monodevelop started to throw strange exceptions at my face about Format error occuring when parsing a string with double.Parse(). This was triggered in various places ranging from startup, project opening, file opening or application unloading. At the time I hadn't bothered tracking down the issue but last Monday I decided to investigate it. Turned out that double.Parse was throwing a FormatException about '.' (like in "12.68") which was considered unknown.

After poking and modifying some stuff in Double.cs the problem was remaining. So, I made a really simple test case that I pasted below :

using System;

class DoubleFormatTestCase
{
  public static void Main()
  {
	Console.WriteLine(double.Parse("12.68"));
  }
}

Compiling it and running it on my machine threw the same exception that in Monodevelop. I admit this puzzled me completely as I was thinking that, programming language speaking, floating numbers were always represented like this in their textual form.

After asking in #mono, yakeen suggested replacing the simple double.Parse(string) with double.Parse(string, CultureInfo) like this :

using System;
using System.Globalization;
class DoubleFormatTestCase
{
  public static void Main()
  {
	Console.WriteLine(double.Parse("12.68",
                    CultureInfo.InvariantCulture.NumberFormat));
  }
}

And if you try this code it should work no matter your platform or your language.

Why that ? Because as you should know (and as I should have remembered :P ) .NET/Mono enforces that things like string comparisons, DateTime handling or long.Parse (in our case) are made according to the user culture. Indeed, here in France, when we write floating numbers, we use ',' and not '.' to separate the integer and floating part. This syntax difference explained why long.Parse(string) was borking on my system.

You can also re-run the first test like this : LANG=en_EN mono DoubleFormatTestCase.exe. Normally it should run without problem.

The moral of the story : always use double.Parse(string, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); instead of double.Parse(string) when doing conversion between string and double in a persistent way (configuration files, intern calculations) and only use the latter when you have to exchange with the user.

Btw, with big kudos to yakeen, I submitted a patch to Monodevelop to correct the problem. It should be available soon.