简体   繁体   English

C#decimal.Parse行为

[英]C# decimal.Parse behaviour

Short question: 简短的问题:

Why are these ' ..... ' valid for parsing a decimal in .NET (C#): 为什么这些' ..... '在.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

What's the reason for this? 这是什么原因?

It fails for me. 它失败了。 Are you by any chance in a culture where "." 你是否有机会参加“。”文化。 is the thousands separator and "," is the decimal point? 千位分隔符和“,”是小数点? Decimal.Parse (and similar calls) use the thread's current culture by default. Decimal.Parse (和类似的调用)默认使用线程的当前文化。 Whether that is a good thing or not is debatable, but irrelevant to actual behaviour :) 这是否是一件好事是有争议的,但与实际行为无关:)

Try specifying CultureInfo.InvariantCulture in the decimal.Parse call: 尝试在decimal.Parse调用中指定CultureInfo.InvariantCulture

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

I believe that will behave as you expected. 我相信这会表现得像你期望的那样。

I would imagine it's because the parser doesn't actually care about group separators - they are irrelevant to the process of converting a string to a decimal. 我想这是因为解析器实际上并不关心组分隔符 - 它们与将字符串转换为小数的过程无关。

We call them thousands separators, but they're really not. 我们称他们为千位分隔符,但他们真的不是。 They are group separators - you could split every 3 digits, every 10 digits, every 1 digit, so why not every 0 digits? 它们是组分隔符 - 你可以每1位数,每10位数,每1位数,所以为什么不是每0位数?

Interestingly, the code has changed for .NET 4 - this is the relevant output from Reflector for me: 有趣的是,.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;
}

I don't know why, but I know how it works (decimal parser code part see below). 我不知道为什么,但我知道它是如何工作的(十进制解析器代码部分见下文)。 I think last else if just turn on point flag and skip all points. 如果只是打开点旗并跳过所有点,我想最后一个。

    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;
    }
}

Use Reflector tool to investigate all code. 使用Reflector工具调查所有代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM