C# Int32.Parse vs Single.Parse-(“1234”和(“1,2,3,4”)。为什么int和浮点类型解析分隔符的方式不同?

C# Int32.Parse vs Single.Parse-(“1234”和(“1,2,3,4”)。为什么int和浮点类型解析分隔符的方式不同?,c#,.net,parsing,floating-point,int,C#,.net,Parsing,Floating Point,Int,在C#中: 这会抛出一个格式异常,它似乎不应该: Int32.Parse("1,234"); 但事实并非如此,这似乎很正常: Single.Parse("1,234"); 令人惊讶的是,这解析得很好: Single.Parse("1,2,3,4"); //Returns 1234 我的本地文化是EN-US,因此默认的字符是, 主要问题:为什么不一致 另外:为什么解析(“1,2,3,4”)有效?它似乎只是在解析之前删除本地分隔符char的所有实例。我知道在正则表达式检查或类似的东西中会有额

在C#中:

这会抛出一个
格式异常
,它似乎不应该:

Int32.Parse("1,234");
但事实并非如此,这似乎很正常:

Single.Parse("1,234");
令人惊讶的是,这解析得很好:

Single.Parse("1,2,3,4"); //Returns 1234

我的本地文化是EN-US,因此默认的字符是

主要问题:为什么不一致

另外:为什么
解析(“1,2,3,4”)
有效?它似乎只是在解析之前删除本地分隔符char的所有实例。我知道在正则表达式检查或类似的东西中会有额外的运行时开销,但是数字文字“1,2,3,4”什么时候不是打字错误呢


相关的: 我的是es 在这些上面。是默认的千位分隔字符,而“,”是int和double之间的分隔字符 所以 任何像“1.2.3,4”这样的解析都会给我“123,40”(在我们身上是123.40) 如果我把“.”放在“,”之前,比如“123,4.3”,它会给出错误 但是,同样的问题说,如果我把“1.2.3.4”放在“1234”上
因此,它可能是.net本身的一项功能。

对于第一种情况,默认情况下来自
Int32.Parse
实现但不实现
numberstyle.AllowThousands

public static int Parse(String s) {
    return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
因此,不允许使用任何逗号分隔符。这:

Int32.Parse("1,234");

两者都是错误的。在任何文化中

要解决此问题,必须将
NumberStyles.AllowThousands
添加到
NumberStyles
中,这将允许在
EN-US
区域性中解析“1234”:

Int32.Parse("1,234", NumberStyles.Integer | NumberStyles.AllowThousands);
但是

仍将
抛出
异常


对于第二种情况,根据,
Single.Parse的默认样式为:

public static float Parse(String s) {
    return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}
这是允许的。而
,“
EN-US
文化中被识别为千位分隔符,用于
Single.Parse
,因此您可以正确解析第二个案例

Single.Parse("1,234"); //OK
很明显,“1.234”也是正确的,除了“.”不被认为是千位分隔符,而是十进制分隔符


至于第三种情况
Single.Parse
调用
TryStringToNumber
,这将忽略1000个分隔符。因此,你得到:

Single.Parse("1,2,3,4"); //Returns 1234 
因为它相当于

Single.Parse("1234"); //Returns 1234 
根据:

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

[ws][sign]位[ws]


使用NumberStyles.Integer样式解释s参数。除十进制数字外,只允许使用带前导符号的前导空格和尾随空格

就是这样,NumberStyles.Integer不允许解析方法使用千分分隔符,而默认情况下使用NumberStyles.Float和NumberStyles.AllowThousands。可以通过将第二个参数指定为NumberStyles来更改此行为:


Parse忽略分组,根本不使用特定于区域性的,只确定字符是组分隔符还是十进制分隔符。组大小仅在格式化数字时使用。

<代码>Single.Parse(“1,2,3,4”,NumberFormatInfo.InvariantInfo)还输出
1234
。此处没有不一致之处
Int32.Parse()
第二个参数默认为
NumberStyles.Integer
,不支持千位分隔符。另一方面,
Single.Parse()。请参阅中的备注部分。@FrédéricHamidi我仍然认为
Int32
Single
的解析默认值不一致。不一致性是可以解释的事实并不能使它们保持一致。@FrédéricHamidi这似乎就是不一致性的定义。对于第三个例子,解析器只是从字符串中删除了数千个分隔符-这是解析器的一部分。OP不是说
Int32.Parse(“1234”)抛出一个
格式异常
Single.Parse("1,2,3,4"); //Returns 1234 
Single.Parse("1234"); //Returns 1234 
Int32.Parse("1,234", NumberStyles.AllowThousands); //works