I'd like to know if I'm missing something or not... I'm running under the standard Great British culture.
Double result = 0;
if (Double.TryParse("1,2,3", NumberStyles.Any, CultureInfo.CurrentCulture, out result))
{
Console.WriteLine(result);
}
Expected output would be nothing... "1,2,3" shouldn't parse as a double. However it does. According to the .NET 2.0 MSDN documentation
AllowThousands Indicates that the numeric string can have group
separators; for example, separating the hundreds from the thousands.
Valid group separator characters are determined by the
NumberGroupSeparator and CurrencyGroupSeparator properties of
NumberFormatInfo and the number of digits in each group is determined
by the NumberGroupSizes and CurrencyGroupSizes properties of
NumberFormatInfo.
Allow thousands is included in NumberStyles.Any. The NumberGroupSizes is 3 for my culture. Is this just a bug in the Double.Parse? seems unlikely but I can't spot what I'm doing wrong....
It just means the input string can contain zero or more instances of NumberFormatInfo.NumberGroupSeparator
. This separator can be used to separate groups of numbers of any size; not just thousands. NumberFormatInfo.NumberGroupSeparator
and NumberFormatInfo.NumberGroupSizes
are used when formatting decimals as strings. Using Reflector it seems like NumberGroupSeparator
is only used to determine if the character is a separator, and if it is, it is skipped. NumberGroupSizes
is not used at all.
If you want to validate the string, you could do so using RegEx or write a method to do so. Here's one I just hacked together:
string number = "102,000,000.80";
var parts = number.Split(',');
for (int i = 0; i < parts.Length; i++)
{
var len = parts[i].Length;
if ((len != 3) && (i == parts.Length - 1) && (parts[i].IndexOf('.') != 3))
{
Console.WriteLine("error");
}
else
{
Console.WriteLine(parts[i]);
}
}
// Respecting Culture
static Boolean CheckThousands(String value)
{
String[] parts = value.Split(new string[] { CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator }, StringSplitOptions.None);
foreach (String part in parts)
{
int length = part.Length;
if (CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes.Contains(length) == false)
{
return false;
}
}
return true;
}