Какие «Числовые стили» используются для разбора и двойного ввода.Разобрать?

#c# #.net

Вопрос:

В C#/.NET для чего используются NumberStyles , когда вызываются методы Double.Parse(string, IFormatProvider) и Int32.Parse(string, IFormatProvider) ?

Документация (Двойная.Разбор, Int32.Разбор) не совсем ясно об этом. Перегрузка .Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider) предполагает следующее:

  • Двойной: NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowThousands | NumberStyles.AllowTrailingWhite | NumberStyles.Float | NumberStyles.Integer
  • Int32: NumberStyles.Integer

Под перегрузкой Double.Parse(string, NumberStyles, IFormatProvider) имеется следующее расплывчатое и противоречивое утверждение:

Типичное значение, которое необходимо указать Float , объединяется с AllowThousands .

Может кто-нибудь прояснить это?

/Обновление: Я взглянул на разборку и обнаружил, что Double.Parse(string, IFormatProvider) перенаправляет на последнюю перегрузку и действительно применяется Float | AllowThousands для NumberStyles аргумента.

Комментарии:

1. Почему документация не ясна? Я вижу, что вы связались с немецкой версией. По крайней мере, в английской версии он точно указывает, какие стили чисел используются в разделе «Примечания».

2. Это также заставляет меня задаться вопросом, почему вы обратились к документации по Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider) перегрузке, когда спрашиваете о Parse(string, IFormatProvider) перегрузке…

3. @Sweeper, не могли бы вы тогда указать, что такое значение по умолчанию? В разделе Примечания я могу видеть только описание различных NumberStyles значений, но не то, что используется по умолчанию, если параметр опущен . Есть только расплывчатое утверждение «Типичное значение для указания-это значение с плавающей точкой в сочетании с разрешенными тысячами» (интересно, что это противоречит значению по умолчанию, используемому для ReadOnlySpan<> перегрузки.

Ответ №1:

Это позволяет изменить строгость C# при обработке входных данных

 //all work because c# allows you to put thousands separators, decimals, whitespace etc ( , in my culture btw) by default
double.Parse("1234.56");
double.Parse("1,234.56");
double.Parse(" 1,234.56");

//fails because the given flags permit the input to only contain a decimal point. The , will cause "Input not in a correct format" exception
double.Parse("1,234.56", NumberStyles.AllowDecimalPoint);
    
//works because the given flags permit the input to contain a decimal point and thousands sep
double.Parse("1,234.56", NumberStyles.AllowDecimalPoint|NumberStyles.AllowThousands);
    
//fails because input flags don't permit leading whitespace
double.Parse(" 1,234.56", NumberStyles.AllowDecimalPoint|NumberStyles.AllowThousands);
    
 

и так далее

Ответ №2:

Документация для Double.Parse says:

s Параметр интерпретируется с использованием комбинации флагов NumberStyles.Float и. NumberStyles.AllowThousands

И для Int32.Parse :

s Параметр интерпретируется с использованием NumberStyles.Integer стиля.

Вы также можете видеть, что это действительно так в исходном коде Int32.Parse

     public static int Parse(string s, IFormatProvider? provider)
    {
        if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
        return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
    }
 

и Double.Parse

     public static double Parse(string s, IFormatProvider? provider)
    {
        if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
        return Number.ParseDouble(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider));
    }