问题
The problem: Let's assume you are using a dot "." as a decimal separator in your regional setting and have coded a string with a comma.
string str = "2,5";
What happens when you decimal.TryParse(str, out somevariable);
it?
somevariable
will assume 0.
What can you do to solve it?
1- You can
decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out somevariable);
And it will return 25, and not 2.5 which is wrong.
2- You can
decimal.TryParse(str.Replace(",","."), out num);
And it will return the proper value, BUT, if the user uses ","
as a decimal separator it will not work.
Possible solution that I can't make it work:
Get the user decimal separator in regional settings:
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
And make somehow the replace from ",",sepdec
, that way it would stay a comma if its a comma, and replace by an actual dot if the user uses dots.
Hints?
Edit: Many users posted useful information, lately, using the arguments NumberStyles.Any, CultureInfo.GetCultureInfo("pt-PT")
on a tryParse
wouldn't work if your separator is set to "," So it pretty much doesnt fullfill the premise of making a tryparse "universal".
I'll work around this, if anyone has more hints you'r welcome
回答1:
I know the thread is a little bit older, but I try to provide an answer.
I use regular expression to determine the used number format in the string. The regex also matches numbers without decimal separators ("12345").
var numberString = "1,234.56"; // en
// var numberString = "1.234,56"; // de
var cultureInfo = CultureInfo.InvariantCulture;
// if the first regex matches, the number string is in us culture
if (Regex.IsMatch(numberString, @"^(:?[\d,]+\.)*\d+$"))
{
cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in de culture
else if (Regex.IsMatch(numberString, @"^(:?[\d.]+,)*\d+$"))
{
cultureInfo = new CultureInfo("de-DE");
}
NumberStyles styles = NumberStyles.Number;
bool isDouble = double.TryParse(numberString, styles, cultureInfo, out number);
HTH
Thomas
回答2:
Instead of checking the culture or replace, it's possible to use TryParse and supporting both separators without too much code.
double d;
if (double.TryParse("12.3", System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out d))
Console.WriteLine("Value converted {0}", d);
else
Console.WriteLine("Unable to parse this number");
回答3:
I found a solution, I'm a beginner on this regional and comma-dots theme so if you have comments to improve the understanding of this please be welcome.
We start of by getting what decimal separator the user has set in his regional options outside before the Form{InitializeComponent();}
(I want a universal variable that will allow me to correct the code)
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
In the tryParse
, to get it to behave universally we will read the dots and commas in the string, and turn them into the decimal separator we defined as sepdec
decimal.TryParse(str.Replace(",",sepdec.ToString()).Replace(".",sepdec.ToString()), out somevariable);
I hope this helps, please comment improvement suggestions!
来源:https://stackoverflow.com/questions/29452263/make-tryparse-compatible-with-comma-or-dot-decimal-separator