The string value is "90-". Why does the decimal parse it as "-90" but double throws a FormatException?

var inputValue= "90-";
Console.WriteLine(decimal.Parse(inputValue));
Console.WriteLine(double.Parse(inputValue));
有帮助吗?

解决方案

The decimal.Parse(string s) overload, by default, is called with NumberStyle NumberStyles.Number which is defined as:

Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, and AllowThousands styles are used. This is a composite number style.

Note that AllowTrailingSign is included. If you wish to customize the behaviour then you should explicitly call the overload that allows you to specify a number style and tailor it to your needs.

其他提示

The implementation is different between the two:

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

where

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

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

So decimal.Parse allows trailing signs but double.Parse does not.

Looks like the documentation on MSDN is inaccurate:

Parameter s contains a number of the form:

[ws][sign][digits,]digits[.fractional-digits][ws]

It should indicate that a trailing sign is valid as well.

Interesting, it seems that by default, decimal and double use different number styles:

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

Parameter s is interpreted using the NumberStyles.Number style. This means that white space and thousands separators are allowed but currency symbols are not.

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

The s parameter is interpreted using a combination of the NumberStyles.Float and NumberStyles.AllowThousands flags. This means that white space and thousands separators are allowed, for example, while currency symbols are not.

It's not immediately obvious from those descriptions, but if you look it up, NumberStyles.Number allows trailing sign:

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

Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, and AllowThousands styles are used. This is a composite number style.

Presumably the difference in the defaults is because decimal is often used for currency calculations.

Of course, in both cases you can supply your own number format specifying exactly what you do and don't want to accept so you can make them consistent for your own use.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top