在String.Empty和Null上使用Convert.ToInt32(String)的区别

24

Convert.ToInt32(String.Empty)表达式会引发一个FormatException异常,因为它无法将空字符串解析为Int32值。

然而,在VB.NET中,Convert.ToInt32(DirectCast(Nothing, String))或在C#中Convert.ToInt32((string)null)的表达式将null解析为零的Int32值。

深入研究.NET资源文件中的Convert.cs,可以看到以下代码:

public static int ToInt32(String value) {
    if (value == null) 
        return 0;
    return Int32.Parse(value, CultureInfo.CurrentCulture);
}

这解释了行为,但我想知道为什么它是这样编写的,而不是对于空字符串也返回零?

例如,为什么它没有被写成:

public static int ToInt32(String value) {
    if (String.IsNullOrEmpty(value)) 
        return 0;
    return Int32.Parse(value, CultureInfo.CurrentCulture);
}

(请注意,String.IsNullOrEmpty()Convert.ToInt32() 都可以追溯到 .NET 2.0,或更早的版本。)

编辑:我的问题与此问题非常相似,但我也想知道为什么Convert.ToInt32(String.Empty)会引发异常,而不是返回0 的 Int32 默认值。(答案是String.Empty 不是String 的默认值,因此没有关联)


6
Null可以看作是数据的缺失,而空字符串一个字符串,只不过是一个空的字符串,它并不是一个数字。(个人认为null不应该如此宽容,但这是另外一回事。) - Jon Skeet
如果你真的想要用这种类型的问题来震撼自己,那就比较一下 SQL 中的 NULL 和 C# 中的 null - P.Brian.Mackey
1
有趣的问题。说实话,我认为这是一个糟糕的设计选择。在我看来,既不是 null 也不是 "" 是有效的整数,两者都应该引发异常。 - Andre Loker
我期望这个API会抛出一个NullReferenceException,而不是返回默认值。从.NET框架API的其余部分来看,这应该是最合理的做法。 - Steven
2
截至目前,针对“重复”问题的第二个答案回答了这个问题(即“为什么”部分):https://dev59.com/X2gu5IYBdhLWcg3wGjZF#11580256 - JDB
显示剩余4条评论
1个回答

10

我对实际设计团队的原因毫无见解,但在我看来,这可能是某种“默认值等价性”。 空值是字符串的默认值,因此将其转换为int的默认值似乎是合理的。 但是,String.Empty像任何其他非空字符串数据一样是一个字符串,因此应该进行格式化,因此会出现异常。

我认为ArgumentNullException可能是一个更“清晰”的决定,但我不知道背后可能有什么内部问题……

另一个编辑:
MSDN文档中,有五个可能的结果之一:

成功转换。 对于不在以前结果中列出的两个不同基类型之间的转换,所有扩大转换以及不导致数据丢失的所有缩小转换都将成功,并且该方法将返回目标基类型的值。

从空对象到另一种类型的转换似乎没有失败的理由(不是格式错误,不是不支持的类型转换),但是值类型(例如int)没有表示“无数据”的方式,因此产生了目标类型的默认值。

一个快速的想法-“相反”的转换Convert.ToString(0)不会产生空值,因为:

  • 0是数据,在许多情况下可能是非常有效和重要的值
  • null不是0的正确字符串表示形式

我会接受这个答案,因为它满足了我的好奇心。@Cyborgx37在对原问题的评论中提到的"https://dev59.com/X2gu5IYBdhLWcg3wGjZF#11580256"中的"VB6 Legacy Support"回答对我来说也是一个有效的理由。 - MCattle
3
非常有趣。与今天的 XKCD 漫画相关 :) http://xkcd.com/1172/ - Honza Brestan
我认为这个理由站不住脚,因为根据 MSDN 链接的说明,应该抛出 FormatException,因为“要转换为任何数值类型的字符串未被识别为有效数字”。 - Jonathan
@HonzaBrestan 不确定你如何解释 int.Parse(null) 会引发异常。这是一个奇怪的选择,但我的理由是“因为文档是这样说的”。 - nawfal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接