如果你将null转换为int32
,我今天就遇到过这个问题Convert.ToInt32(null)
它返回0
我期待InvalidCastException ...
知道为什么会这样吗?
答案 0 :(得分:40)
知道为什么会这样吗?
因为这是记录在案的行为?无论是Convert.ToInt32(object)
还是Convert.ToInt32(string)
,文档都说得很清楚:
(在返回值下)
32位有符号整数,等于值中的数字,如果value为null,则为0(零)。
或
等于值的32位有符号整数,如果value为null,则为零。
与往常一样,如果现实与预期不符,那么您应该做的第一件事就是检查您的期望是否符合记录的行为。
就个人而言,我并没有完全购买Gavin所显示的“与VB6的兼容性”这个论点。我意识到它来自微软,它可能是它的行为方式的真正原因 - 但我不认为这是一种良好的理由。有很多特定于VB的转换方法 - 所以如果框架设计者真的认为返回零是一个非理想的结果,他们应该做他们认为最好的事情,并提供VB6兼容的转换供VB6程序员使用。
显然,一旦行为在.NET 1.0中定义,就无法为以后的版本进行更改 - 但这与说它的行为方式与VB6相同并不相同。
答案 1 :(得分:11)
请参阅http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx
修改强>
上面的URL会自动恢复为最新的Framework版本,其中下面的文本专门发布在版本4上。请参阅下面显示文本的修订后的URL。
http://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.100).aspx
它解释道:
如果字符串为null,则Convert类中的所有字符串到数字转换方法都返回零。这种行为的最初动机是它们将为从Visual Basic 6迁移到Visual Basic .NET的程序员提供一组转换方法,这些方法镜像了现有Visual Basic 6转换方法的行为。假设C#程序员更适合使用转换操作符,而Visual Basic传统上使用转换方法进行类型转换。
传统上,.NET Framework一直试图保持版本之间的高度兼容性。实际上,这意味着,如果没有极其令人信服的理由,一旦方法以特定方式实现并且实现被公开暴露(如在字符串参数为null的情况下返回0的方法),则无法更改,因为会破坏依赖于既定行为的代码。这使得您提出的两种解决方案都非常有问题。在第一种情况下,抛出异常会为可能依赖于为null字符串返回零的方法的客户更改方法的实现。在第二种情况下,重要的是要记住.NET Framework不考虑重载决策中的返回类型。这意味着您的方法必须替换现有的Convert.ToInt32(String value)方法,并且所有不期望处理可空类型的代码现在都将被破坏。
对于Convert类中的字符串到数字转换方法,这种兼容性问题甚至更强,因为Parse是为每个支持的原始数字类型执行字符串到数字转换的推荐方法。 .NET Framework,每个Parse方法的行为与其对应的Convert方法不同。与Convert类中的字符串到数字转换方法不同,如果要转换的字符串为null,则返回零,每个Parse方法抛出一个ArgumentNullException,这是您正在争论的行为。数值Parse方法的重载,例如Int32.Parse和Double.Parse,也具有允许对解析操作进行更细粒度控制的优点。
答案 2 :(得分:3)
因为Int32的默认值为零。 Int32不能为null,因为它们是值类型,而不是引用类型,因此您将获得默认值。
答案 3 :(得分:3)
因为它会返回what is documented。也许你在考虑(int)null
,这将是NullReferenceException
(不是InvalidCastException
;我不知道为什么)。
答案 4 :(得分:2)
因为这是在Convert类中编写方法的方法。如果参数值为null
,则只返回0.
public static int ToInt32(object value)
{
if (value == null)
{
return 0;
}
else
{
return ((IConvertible)value).ToInt32(null);
}
}
答案 5 :(得分:1)
如果您有InvalidCastException,则必须进行非受控演员。
例如:
int i = (int)null;
如果执行它,则应引发异常。
使用
Convert.ToInt32(var)
当您不信任 var 中的值时非常有用,就像从数据库中读取时一样。