C# 十进制解析问题

C# 十进制解析问题,c#,.net,type-conversion,C#,.net,Type Conversion,字符串值为“90-”。为什么十进制将其解析为“-90”,但double抛出格式异常 var inputValue= "90-"; Console.WriteLine(decimal.Parse(inputValue)); Console.WriteLine(double.Parse(inputValue)); 默认情况下,decimal.Parse(string s)重载由numberstyle.Number调用,其定义如下: 指示AllowReadingWhite、AllowTrailing

字符串值为
“90-”
。为什么十进制将其解析为
“-90”
,但
double
抛出
格式异常

var inputValue= "90-";
Console.WriteLine(decimal.Parse(inputValue));
Console.WriteLine(double.Parse(inputValue));
默认情况下,
decimal.Parse(string s)
重载由
numberstyle.Number
调用,其定义如下:

指示AllowReadingWhite、AllowTrailingWhite、, AllowReadingSign、AllowTrailingSign、AllowDecimalPoint和 使用AllowThousands样式。这是一种复合数字样式


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

有趣的是,默认情况下,
十进制和
双精度使用不同的数字样式:

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

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

从这些描述中并不明显,但如果您查找它,
numberstyle.Number
允许尾随符号:

指示使用AllowReadingWhite、AllowRailingWhite、AllowReadingSign、AllowRailingSign、AllowDecimalPoint和AllowThousands样式。这是一种复合数字样式

默认值的差异可能是因为
十进制
通常用于货币计算


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

这两种格式的实现方式不同:

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上的内容不准确:

参数s包含以下形式的数字:

[ws][sign][digits,]digits[.小数位数][ws]


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

您的意思是在代码示例中包含
.TryParse
吗?对于
Eric Lippert
来说,这是一个很好的问题,他们只是将不同的默认值传递给数字解析器。
decimal
one被配置为查找常见的货币格式,而
double
one则不是。今天在Int32.Parse中遇到了这个问题-它会像我预期的那样抛出,但decimal.Parse没有。