可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm writing a custom string to decimal validator that needs to use Decimal.TryParse that ignores culture (i.e. doesn't care if the input contains "." or "," as decimal point separator).
This is the suggested method:
public static bool TryParse(
string s,
NumberStyles style,
IFormatProvider provider,
out decimal result
)
I can't figure out what to use as the 3rd parameter. The examples I've seen look like this:
culture = CultureInfo.CreateSpecificCulture("en-GB");
Decimal.TryParse(value, style, culture, out number)
so they create a specific culture. CultureInfo does not have a "CreateInvariantCulture" method, and CultureInfo.InvariantCulture is not of the required type.
What's the correct usage?
回答1:
Have try like this :
decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);
The best way would likely be to use the Decimal.Parse() method as you would traditionally with any decimal string values.
You can use NumberStyles.Currency to specify that the values be read in as currency, which will take care of any currency-related values (you will need to add a Reference to System.Globalalization to use this :
using System.Globalization;
Decimal.Parse also accepts a third-parameter, which will allow you to explicitly set the IFormatProvider
if you so choose and wish to you a specific Culture :
decimal value = Decimal.Parse(currency, NumberStyles.Currency, CultureInfo.InvariantCulture); //yields 15.55
回答2:
My bad guys. I tested the following code:
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();
and it correctly parses both strings. Seems like the default TryParse is indeed culture invariant. I assumed this was not the case, because the default TypeConversionValidator in EnterpriseLibrary was culture dependent and I assumed it simply used TryParse. However, as it turns out this default parser is hardcoded to use current culture.
EDIT: I found out that "1.5" converts to 1.5 and "1,5" converts to 15. This is actually correct for culture invariant behavior, so there it is. This whole question was apparently spawned by my misunderstanding of how culture invariant works.
回答3:
In fact CultureInfo.InvariantCulture
can be used here. The parameter expects IFormatProvider
, an interface that CultureInfo
implements. But InvariantCulture
is invariant in the sense that it does not vary with the user's settings.
In fact, there is no culture that accepts either ,
or .
as decimal separator – they are all one or the other. You'll have to find some other way to deal with data which can use either of these decimal separators.
回答4:
I can't figure out what to use as the 3rd parameter.
Because all cultures NumberDecimalSeparator
or NumberGroupSeparator
etc.. are not the same.
Someones uses .
as a NumberDecimalSeparator
, someone uses ,
but there is no CultureInfo
that uses both as a NumberDecimalSeparator
.
CultureInfo
implements IFormatProvider
interface. That's why if you specify your CultureInfo
, your value
string try to be parsed on that cultures rules.
I'm writing a custom string to decimal validator that needs to use
Decimal.TryParse that ignores culture
In such a case, you can use CultureInfo.Clone
method to copy of which culture you want (or InvariantCulture
) and you can set NumberDecimalSeparator and NumberGroupSeparator which string you want.