Double.TryParse () игнорирует NumberFormatInfo.NumberGroupSizes? - PullRequest
7 голосов
/ 16 января 2012

Я хотел бы знать, что я что-то упустил или нет ... Я работаю в соответствии со стандартной британской культурой.

Double result = 0;
if (Double.TryParse("1,2,3", NumberStyles.Any, CultureInfo.CurrentCulture, out result))
{
   Console.WriteLine(result);
}

Ожидаемый результат будет ничем ... "1, 2,3 "не должны восприниматься как двойные.Однако это так.Согласно документации .NET 2.0 MSDN

AllowThousands Указывает, что числовая строка может иметь разделители групп;например, отделяя сотни от тысяч.Допустимые символы разделителя групп определяются свойствами NumberGroupSeparator и CurrencyGroupSeparator в NumberFormatInfo, а количество цифр в каждой группе определяется свойствами NumberGroupSizes и CurrencyGroupSizes для NumberFormatInfo.

Разрешить тысячи включается в NumberStyles.Any,NumberGroupSizes 3 для моей культуры.Это просто ошибка в Double.Parse?кажется маловероятным, но я не могу определить, что я делаю неправильно ...

1 Ответ

5 голосов
/ 16 января 2012

Это просто означает, что входная строка может содержать ноль или более экземпляров NumberFormatInfo.NumberGroupSeparator. Этот разделитель можно использовать для разделения групп чисел любого размера; не только тысячи. NumberFormatInfo.NumberGroupSeparator и NumberFormatInfo.NumberGroupSizes используются при форматировании десятичных чисел как строк. При использовании Reflector кажется, что NumberGroupSeparator используется только для определения, является ли символ разделителем, и если это так, он пропускается. NumberGroupSizes вообще не используется.

Если вы хотите проверить строку, вы можете сделать это с помощью RegEx или написать метод для этого. Вот что я только что взломал вместе:

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;
}
...