使用IL中的Initobj操作码初始化可空类型

时间:2012-06-04 21:45:48

标签: c# .net struct nullable il

为什么C#编译器不会为.ctor分配的可空值类型调用默认的隐式无参数intobj而不是null

让我们说我们有代码:

Nullable<int> ex1 = new Nullable<int>();
Nullable<int> ex2 = null;
Nullable<int> ex3 = new Nullable<int>(10); 

这两行的IL输出如下所示:

enter image description here

它只为最后一个语句调用.ctor,为什么我们不能拥有两个带有归零字段的第一个语句的实例?

3 个答案:

答案 0 :(得分:5)

  

为什么C#编译器不会为null赋值的可空值类型调用默认的隐式无参数.ctor而不是intobj

因为Nullable<T>(或任何其他值类型)实际上没有无参数构造函数。您可以通过在反编译器中查看或使用反射(例如typeof(Nullable<>).GetConstructors())来验证它。

如果在C#中为某些值类型new T()编写T,它看起来像是调用无参数构造函数(并且C#规范也将其称为构造函数),但这不是实际发生的情况,因为值类型没有无参数.ctor方法。

答案 1 :(得分:1)

  

为什么C#编译器只调用默认的隐式无参数.ctor

因为像value type这样的System.Nullable<T>不能包含显式的无参数构造函数;这是定义值类型的要求。因为值类型不能具有显式的无参数构造函数,initobj是在CIL中默认构造值类型的唯一方法。

答案 2 :(得分:0)

因为initobj指令初始化了一个值类型并将其字段归零或为空,按照MSDN documentation.调用默认构造函数方法而不提供额外的值。您的上一个示例传入一个值,因此称为非常具体的构造函数。