2012-06-04 29 views
3

爲什麼C#編譯器只是簡單地調用默認的隱式無參數.ctor而不是intobjnull指定了可爲空的值類型?用IL中的Initobj操作碼初始化可空類型

假設我們有這樣的代碼:

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()在C#中的一些價值型T,它看起來像它調用參數的構造函數(和C#規範要求它的構造太),但是這不是實際發生的事情,因爲沒有參.ctor方法值類型。

+0

好吧,你說的很對,因爲我的圖片顯示如果有一個,它也會在IL中調用,但是,它調用'intobj'指令來初始化值類型,即使我說'new Nullable ()' 。我正在將你的帖子標記爲答案。 – Tarik

1

爲什麼不C#編譯器簡單地調用默認的隱含參數的.ctor

因爲value typeSystem.Nullable<T>不能包含一個明確的參數構造函數;這是定義值類型的要求。因爲值類型不能有明確的無參數構造函數,所以initobj是在CIL中默認構建值類型的唯一方法。

+0

這不是快捷方式,這是調用它的唯一方法。我不確定我會說它沒有代碼,因爲它仍然需要初始化所有字段。 – svick

+0

不,它沒有,因爲那是'initobj'的工作。我已經編輯了我的答案,以便更清楚。 –

0

由於initobj指令初始化值類型和零或空出其字段,按照MSDN documentation.調用默認的構造方法在頂部的,提供沒有附加價值。你的最後一個例子傳入一個值,因此稱爲一個非常具體的構造函數。