我刚从一位让我发疯的同事那里得到了这个测验。对于这段代码:
var x = new Int32?();
string text = x.ToString(); // No exception
Console.WriteLine(text);
Type type = x.GetType(); // Bang!
为什么第一部分 .ToString() 可以正常工作而不会引发异常,然后对 GetType() 的调用会引发 NullReferenceException ?
ToString
在 中被覆盖Nullable<T>
,因此拨打电话时不涉及拳击。
GetType()
不是虚拟方法,因此不会(也不能)被覆盖,因此在调用之前将值装箱......并且装箱可空值类型的空值会给出空引用。
装箱的原因在 C# 4 规范的第 7.5.5 节中:
If
M
是在引用类型中声明的实例函数成员:
- ...
- 如果 of 的类型
E
是value-type,则执行装箱转换(4.3.1)转换E
为 typeobject
,并在以下步骤中E
被认为是 type 。object
在这种情况下,M
只能是System.Object
请注意,如果您有:
var x = new Int32?(10);
typeof(int)
由于拳击,你最终会得到与 相同的类型。无法使用普通方法创建返回可空值类型的foo
值。(您当然可以创建一个新方法,但这是一个附带问题:)foo.GetType()
GetType()
GetType()
(使用“Bang!”表明该测验的作者可能是我。如果是这样的话,抱歉让你发疯。)