Инвариант культуры Decimal.TryParse()

Я пишу пользовательскую строку для десятичного валидатора, который должен использовать Decimal.TryParse, который игнорирует культуру (т.е. не заботится о том, содержит ли ввод «.» или «,» в качестве разделителя десятичной точки). Это предлагаемый метод:

public static bool TryParse(
    string s,
    NumberStyles style,
    IFormatProvider provider,
    out decimal result
)

Я не могу понять, что использовать в качестве третьего параметра. Примеры, которые я видел, выглядят так:

culture = CultureInfo.CreateSpecificCulture("en-GB");
Decimal.TryParse(value, style, culture, out number)

поэтому они создают определенную культуру. В CultureInfo нет метода CreateInvariantCulture, а CultureInfo.InvariantCulture не относится к требуемому типу. Каково правильное использование?


person Shaggydog    schedule 17.04.2014    source источник


Ответы (4)


На самом деле здесь можно использовать CultureInfo.InvariantCulture. Параметр ожидает IFormatProvider, интерфейс, который реализует CultureInfo. Но InvariantCulture является инвариантным в том смысле, что он не меняется в зависимости от настроек пользователя.

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

person David Heffernan    schedule 17.04.2014

Мои плохие парни. Я протестировал следующий код:

        string DutchDecimal = "1,5";
        string EnglishDecimal = "1.5";
        decimal a;
        decimal b;
        Console.WriteLine(decimal.TryParse(DutchDecimal, out a));
        Console.WriteLine(a);
        Console.WriteLine(decimal.TryParse(EnglishDecimal, out b));
        Console.WriteLine(b);
        Console.Read();

и он правильно анализирует обе строки. Похоже, что TryParse по умолчанию действительно инвариантен к культуре. Я предположил, что это не так, потому что TypeConversionValidator по умолчанию в EnterpriseLibrary зависит от культуры, и я предположил, что он просто использует TryParse. Однако, как оказалось, этот синтаксический анализатор по умолчанию жестко закодирован для использования текущей культуры.

РЕДАКТИРОВАТЬ: я обнаружил, что «1,5» преобразуется в 1,5, а «1,5» преобразуется в 15. На самом деле это правильно для инвариантного поведения культуры, так что вот оно. Весь этот вопрос, по-видимому, возник из-за моего непонимания того, как работает культурный инвариант.

person Shaggydog    schedule 17.04.2014
comment
Из документации Microsoft это выглядит так: .NET обращается к вашим локальным системным настройкам, если вы не укажете культуру: Parameter s is parsed using the formatting information in a NumberFormatInfo object initialized for the current system culture. - person Rune Vejen Petersen; 17.08.2016
comment
Разбирать от 1,5 до 15 не совсем правильно, не так ли? Если ',' является разделителем тысяч, его нельзя допускать на 10-й позиции. Я думаю, что синтаксический анализ 1,5 с использованием инвариантного синтаксического анализа культуры должен завершиться неудачно. - person avl_sweden; 26.06.2017
comment
@avl_sweden неправильно предполагать, что запятая является разделителем тысяч, если это не десятичный разделитель. Например, если Швеция напишет 1 234 567,89, Индия напишет 12 34 567,89, а Китай напишет 123 4567,89. Форматирование чисел не так просто. Я предполагаю, что когда запятая не является десятичным разделителем, синтаксический анализатор просто полностью игнорирует ее. - person Peter; 27.09.2018
comment
@Peter 1 234 567,89 не соответствует шведскому языку. Мы используем пробелы в качестве разделителя тысяч и запятую в качестве десятичного разделителя. - person Mattias Örtenblad; 08.05.2019
comment
На самом деле это зависит от вашей текущей локали, и в вашем случае кажется, что точка видна как десятичный разделитель. У меня установлен голландский язык, и он фактически анализирует «1,5» до «15». Поэтому, если вы теперь полагаетесь на то, что «1,5» фактически преобразуется в «15», вас может удивить, если ваше приложение запускается на другом компьютере с другими настройками локали. - person SuperDre; 19.05.2020

Я не могу понять, что использовать в качестве третьего параметра.

Поскольку все языки и региональные параметры NumberDecimalSeparator< /a> или NumberGroupSeparator и т. д. не совпадают.

Кто-то использует . как NumberDecimalSeparator, кто-то использует ,, но нет CultureInfo, который использует оба как NumberDecimalSeparator.

CultureInfo реализует < интерфейс href="http://msdn.microsoft.com/en-us/library/System.IFormatProvider.aspx" rel="nofollow">IFormatProvider. Вот почему, если вы укажете свой CultureInfo, ваша строка value попытается проанализировать правила этой культуры.

Я пишу пользовательскую строку для десятичного валидатора, который должен использовать Decimal.TryParse, который игнорирует культуру

В таком случае вы можете использовать CultureInfo.Clone, чтобы скопировать нужный язык и региональные параметры (или InvariantCulture), и вы можете установить NumberDecimalSeparator и NumberGroupSeparator, какую строку вы хотите.

person Soner Gönül    schedule 17.04.2014

Я знаю, что это очень старый вопрос, но он все еще появляется при поиске синтаксического анализа с инвариантной культурой.

Я нашел следующее в документация:

Инвариантная культура нечувствительна к культуре. Ваше приложение указывает инвариантный язык и региональные параметры по имени с помощью пустой строки ("") или по ее идентификатору.

Итак, используя эти знания, вы можете создать инвариантную культуру следующим образом:

culture = new CultureInfo(string.Empty);
person mfas    schedule 08.11.2019
comment
CultureInfo уже имеет общедоступное статическое свойство InvariantCulture для этой цели. - person yv989c; 27.09.2020