C#decimal.Parse行为

简短的问题:

为什么这些’ ….. ‘在.NET(C#)中解析小数有效:

decimal res = decimal.Parse("8......15"); // returns 815 decimal res = decimal.Parse("8...15"); // returns 815 decimal res = decimal.Parse("8..15"); // returns 815 

这是什么原因?

它失败了。 你是否有机会参加“。”文化。 千位分隔符和“,”是小数点? Decimal.Parse (和类似的调用)默认使用线程的当前文化。 这是否是好事是有争议的,但与实际行为无关:)

尝试在decimal.Parse调用中指定CultureInfo.InvariantCulture

 decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture); 

我相信这会表现得像你期望的那样。

我想这是因为解析器实际上并不关心组分隔符 – 它们与将字符串转换为小数的过程无关。

我们称他们为千位分隔符,但他们真的不是。 它们是组分隔符 – 您可以每1位数每10位数分割一次,所以为什么不是每0位数?

有趣的是,.NET 4的代码已经改变了 – 这是我对Reflector的相关输出:

 else { if (((currencySymbol == null) || ((chPtr2 = MatchChars(p, currencySymbol)) == null)) && ((ansiCurrencySymbol == null) || ((chPtr2 = MatchChars(p, ansiCurrencySymbol)) == null))) { break; } num |= 0x20; currencySymbol = null; ansiCurrencySymbol = null; p = chPtr2 - 1; } 

我不知道为什么,但我知道它是如何工作的(十进制解析器代码部分见下文)。 如果只是打开点旗并跳过所有点,我想最后一个。

  while (true) { if (((ch >= '0') && (ch <= '9')) || (((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None) && (((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F'))))) { //Here goes some code... } else if ((((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None) && ((num & 0x10) == 0)) && (((chPtr2 = MatchChars(p, currencyDecimalSeparator)) != null) || ((flag && ((num & 0x20) == 0)) && ((chPtr2 = MatchChars(p, numberDecimalSeparator)) != null)))) { num |= 0x10; p = chPtr2 - 1; } } 

使用Reflector工具调查所有代码。