Инвариант культуры 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 не является требуемым типом.
Какое правильное использование?
Ответы
Ответ 1
Попробуйте вот так:
decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);
Лучшим способом, вероятно, будет использование метода Decimal.Parse(), как и традиционно с любыми значениями десятичной строки.
Вы можете использовать NumberStyles.Currency, чтобы указать, что значения должны считываться как валюта, которая будет учитывать любые значения, связанные с валютой (вам нужно будет добавить ссылку на System.Globalalization, чтобы использовать это:
using System.Globalization;
Decimal.Parse также принимает третий параметр, который позволит вам явно установить IFormatProvider
, если вы так пожелаете, и пожелаете вам определенной культуры:
decimal value = Decimal.Parse(currency, NumberStyles.Currency, CultureInfo.InvariantCulture); //yields 15.55
Ответ 2
Мои плохие парни. Я проверил следующий код:
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. Однако, как оказалось, этот синтаксический анализатор по умолчанию жестко запрограммирован для использования текущей культуры.
EDIT: я выяснил, что "1,5" преобразуется в 1,5 и "1,5" преобразуется в 15. Это действительно правильно для поведения, связанного с культурой, так что это так. Весь этот вопрос, по-видимому, породил мое непонимание того, как работает инвариант культуры.
Ответ 3
Фактически CultureInfo.InvariantCulture
можно использовать здесь. Параметр ожидает IFormatProvider
, интерфейс, который реализует CultureInfo
. Но InvariantCulture
является инвариантным в том смысле, что он не зависит от пользовательских настроек.
На самом деле нет культуры, которая принимает либо ,
, либо .
как десятичный разделитель - они все одно или другое. Вам нужно будет найти другой способ обработки данных, которые могут использовать любой из этих разделителей.
Ответ 4
Я не могу понять, что использовать в качестве третьего параметра.
Потому что все культуры NumberDecimalSeparator
или NumberGroupSeparator
и т.д. не совпадают.
Кто-то использует .
как NumberDecimalSeparator
, кто-то использует ,
, но нет CultureInfo
, который использует оба как NumberDecimalSeparator
.
CultureInfo
реализует IFormatProvider
интерфейс. Поэтому, если вы укажете свой CultureInfo
, ваша строка value
попытается проанализировать эти правила культур.
Я пишу пользовательскую строку в десятичный валидатор, который должен использовать Decimal.TryParse, игнорирующий культуру
В этом случае вы можете использовать метод CultureInfo.Clone
для копирования какой культуры вы хотите (или InvariantCulture
), и вы можете установить NumberDecimalSeparator и NumberGroupSeparator, какую строку вы хотите.