Search code examples
c#globalizationdecimal-pointregional-settings

Selecting different regional options changes result of the math operation in c#


Im using Visual Studio 2010. My code has a strange behavior

With this code I can parse xml file.

XDocument document = XDocument.Load("http://www.studiovincent.net/list.xml");
XElement resourcesElement = document.Root.Element("resources");
XElement resourceElementVincent = (from resourceElement in resourcesElement.Elements("resource")
                                           where resourceElement.Elements("field").Single(fieldElement => fieldElement.Attribute("name").Value == "name").Value == "Vincent"
                                           select resourceElement).Single();

decimal tasso = Math.Round(decimal.Parse(resourceElementVincent.Elements("field").Single(fieldElement => fieldElement.Attribute("name").Value == "age").Value) / Convert.ToInt64(1.00E+006), 6);


string gigi = Math.Round(41 * tasso, 4).ToString();
Console.WriteLine("{0}", gigi);
Console.ReadLine();

All work correctly, until I change regional options. If I select italian:

enter image description here

This is OUTPUT: 0,0013

enter image description here

If I select United States in regional options, this is OUTPUT: 0.0000

enter image description here

I dont know how to solve this issue.

Thanks in advance.


Solution

  • decimal.Parse(string) uses the current system format; thus

    decimal.Parse(resourceElementVincent.Elements("field")
           .Single(fieldElement => fieldElement.Attribute("name").Value == "age")
           .Value)
    

    will return zero when Vincent's age is set to 0.27 and the current culture is Italian (where the NumberDecimalSeparator is a comma).

    However, you could use the decimal.Parse(string, IFormatProvider) method instead, passing the InvariantCulture (where the NumberDecimalSeparator is a period):

    decimal.Parse(resourceElementVincent.Elements("field")
           .Single(fieldElement => fieldElement.Attribute("name").Value == "age")
           .Value, CultureInfo.InvariantCulture);
    

    MSDN documentation here.