2012-06-04 2 views
3

Почему компилятор C# просто вызывает неявный параметр без параметров .ctor вместо intobj для null присвоен тип допустимых значений?Инициализация нулевого типа с помощью кода Initobj в IL

Допустим, у нас есть такие, как код:

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

Выход IL для этих двух линий выглядеть следующим образом:

enter image description here

Это только называют .ctor для последнего заявления и почему мы не можем есть экземпляр для двух первых операторов с обнуленными полями?

ответ

4

Почему не C# компилятор просто позвонить по умолчанию неявных .ctor без параметров вместо intobj для нулевого назначенных обнуляемых типов значений?

Поскольку Nullable<T> (или любой другой тип значения) фактически не имеет конструктора без параметров. Вы можете проверить это, посмотрев на него в декомпиляторе или используя отражение (например, typeof(Nullable<>).GetConstructors()).

Если вы пишете new T() для некоторого типа значения T в C#, похоже, это вызывает конструктор без параметров (и C# спецификация называют это конструктор тоже), но это не то, что на самом деле происходит, потому что нет без параметров .ctor метода по типам значений.

+0

Хорошо, что мои фотографии показывают, что если бы их было, то это было бы вызвано и в IL, но вместо этого оно вызывает инструкцию 'intobj', чтобы инициализировать тип значения, хотя я сказал« new Nullable () ' , Я отмечаю ваш пост как ответ. – Tarik

1

Почему не # компилятор C просто позвонить по умолчанию неявно без параметров .ctor

Поскольку value type как System.Nullable<T> не может содержать явный конструктор без параметров; это требование для определения типа значения. Поскольку один тип значения не может иметь явный конструктор без параметров, initobj - единственный метод по умолчанию - построить тип значения в CIL.

+0

Это не ярлык, это единственный способ назвать это. И я не уверен, что скажу, что у него нет кода, потому что он все равно должен инициализировать все поля. – svick

+0

Нет, это не так, потому что это работа 'initobj'. Я отредактировал свой ответ, чтобы быть более ясным. –

0

Поскольку initobj инструкция инициализирует тип значения и нули или аннулирует из его полей, в соответствии с MSDN documentation. Вызов конструктора по умолчанию метод на вершине, что не дает никакой дополнительной ценности. Ваш последний пример передает значение и поэтому называется очень специфическим конструктором.