C# 可为null的类型GetType()引发异常
我刚从一位同事那里得到了一个让我发疯的测验。对于这段代码:C# 可为null的类型GetType()引发异常,c#,.net,C#,.net,我刚从一位同事那里得到了一个让我发疯的测验。对于这段代码: var x = new Int32?(); string text = x.ToString(); // No exception Console.WriteLine(text); Type type = x.GetType(); // Bang! 为什么第一部分.ToString()工作时不会引发异常,而对GetType()的调用会引发NullReferenceException?ToString是,因此调用时不需要装箱 GetTy
var x = new Int32?();
string text = x.ToString(); // No exception
Console.WriteLine(text);
Type type = x.GetType(); // Bang!
为什么第一部分.ToString()工作时不会引发异常,而对GetType()的调用会引发NullReferenceException?ToString
是,因此调用时不需要装箱
GetType()
不是虚拟方法,因此不是(也不能)重写,因此在调用之前将值装箱。。。装箱一个可空值类型的空值会给出一个空引用
装箱原因见C#4规范第7.5.5节:
如果M
是引用类型中声明的实例函数成员:
- 如果
的类型是值类型,则执行装箱转换(4.3.1)以将E
转换为类型E
,并且在以下步骤中将对象
视为类型E
。在这种情况下,对象
只能是M
System.Object的成员
var x = new Int32?(10);
由于装箱,最终的类型与typeof(int)
相同。使用普通的GetType()
方法,无法创建值foo
,从而foo.GetType()
返回可为空的值类型。(当然,您可以创建一个新的GetType()
方法,但这是一个次要问题:)
(使用“砰!”意味着上述测验的作者可能是我。如果是这样的话,我很抱歉让你发疯。)好的。。但是为什么要将最后一行替换为:var boxed=(Int32)x;而是引发InvalidOperationException?这不是装箱,应该引发相同的异常吗?@kabaros:不,这根本不是装箱-
Int32?
和Int32
都不是引用类型。这是C#4规范第6.2.3节中描述的显式转换。哦,是的,当然,这非常有意义。谢谢。顺便说一句,这本书很棒,所以你让我们发疯是可以原谅的:)