10

我刚从一位让我发疯的同事那里得到了这个测验。对于这段代码:

var x = new Int32?();
string text = x.ToString(); // No exception
Console.WriteLine(text);
Type type = x.GetType(); // Bang!

为什么第一部分 .ToString() 可以正常工作而不会引发异常,然后对 GetType() 的调用会引发 NullReferenceException ?

4

1 回答 1

19

ToString在 中被覆盖Nullable<T>,因此拨打电话时不涉及拳击。

GetType()不是虚拟方法,因此不会(也不能)被覆盖,因此在调用之前将值装箱......并且装箱可空值类型的空值会给出空引用。

装箱的原因在 C# 4 规范的第 7.5.5 节中:

IfM是在引用类型中声明的实例函数成员:

  • ...
  • 如果 of 的类型Evalue-type,则执行装箱转换(4.3.1)转换E为 type object,并在以下步骤中E被认为是 type 。object在这种情况下,M只能是System.Object

请注意,如果您有:

var x = new Int32?(10);

typeof(int)由于拳击,你最终会得到与 相同的类型。无法使用普通方法创建返回可空值类型的foo值。(您当然可以创建一个方法,但这是一个附带问题:)foo.GetType()GetType() GetType()

(使用“Bang!”表明该测验的作者可能是我。如果是这样的话,抱歉让你发疯。)

于 2012-10-04T10:50:09.933 回答