十进制解析

时间:2014-04-25 15:22:14

标签: c# .net type-conversion

字符串值为"90-"。为什么小数点会将其解析为"-90",但double会抛出FormatException

var inputValue= "90-";
Console.WriteLine(decimal.Parse(inputValue));
Console.WriteLine(double.Parse(inputValue));

3 个答案:

答案 0 :(得分:15)

默认情况下,decimal.Parse(string s)重载是使用NumberStyle NumberStyles.Number调用的,其定义为:

  

表示AllowLeadingWhite,AllowTrailingWhite,   AllowLeadingSign, AllowTrailingSign ,AllowDecimalPoint和   使用AllowThousands样式。这是一种复合数字样式。

请注意,AllowTrailingSign包含在内。如果您希望自定义行为,那么您应该显式调用重载,以允许您指定数字样式并根据您的需要进行定制。

答案 1 :(得分:8)

两者的实施情况有所不同:

public static double Parse(String s) {
    return Parse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}

public static Decimal Parse(String s) {
    return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
}

其中

NumberStyles.Float     = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | 
                         AllowDecimalPoint | AllowExponent,

NumberStyles.Number    = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
                         AllowDecimalPoint | AllowThousands

因此decimal.Parse允许尾随标志,但double.Parse不允许。

看起来MSDN上的documentation不准确:

  

参数s包含多种形式:

     

[WS] [符号] [数字,]数字[.fractional位数] [WS]

它应该表明尾随符号也是有效的。

答案 2 :(得分:4)

有趣的是,默认情况下,decimaldouble似乎使用不同的数字样式:

http://msdn.microsoft.com/en-us/library/cafs243z.aspx

  

使用NumberStyles.Number样式解释参数s。这意味着允许使用空格和千位分隔符,但不允许使用货币符号。

http://msdn.microsoft.com/en-us/library/fd84bdyt(v=vs.110).aspx

  

使用NumberStyles.Float和NumberStyles.AllowThousands标志的组合解释s参数。这意味着允许使用空格和千位分隔符,例如,货币符号则不允许。

这些描述并不是很明显,但是如果你查一下,NumberStyles.Number允许尾随符号:

http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx

  

表示使用AllowLeadingWhite,AllowTrailingWhite,AllowLeadingSign,AllowTrailingSign,AllowDecimalPoint和AllowThousands样式。这是一种复合数字样式。

据推测,默认值的差异是因为decimal通常用于货币计算。

当然,在这两种情况下,您都可以提供自己的数字格式,明确指出您做什么和不想接受的内容,这样您就可以使它们保持一致,供您自己使用。