2010-04-07 58 views
10

祝賀大家。對不起,如果之前已經問過這個問題(徒勞地搜查過)還是非常簡單,但我無法得到它。可空類型的MSDN definition,聲明,它以如下方式確定:關於可空的<T>約束的困惑

[SerializableAttribute] 
public struct Nullable<T> 
where T : struct, new() 

所以,問題是很簡單:這是怎麼定義的可能嗎?或者這只是一個錯字?每個值類型都有一個默認的構造函數。事實上,當我嘗試編譯這樣的東西時,編譯器合理地說,同時應用兩個約束是非法的,因爲第二個隱含地包含在第一個中。

在此先感謝。

回答

12

我認爲這只是文檔中的一個錯誤。如果您查看反射器中的Nullable<T>類型或使用VS中的「轉到定義」命令,它只會顯示struct約束。


編輯

我有關又在想,我做了一個小測試:

var attributes = typeof(Nullable<>).GetGenericArguments()[0].GenericParameterAttributes; 
Console.WriteLine(attributes); 

此代碼產生以下輸出:

NotNullableValueTypeConstraint, DefaultConstructorConstraint

所以根據反映,TNullable<T>確實new()約束......這意味着,即使它在C#中無效的,它必須是有效的CLR。

因此文檔是正確和錯誤:這是真的,在TNullable<T>有「默認構造函數」的約束,但C#聲明它顯示是錯誤的...

其實,這是不是很奇怪,因爲文檔是從彙編元數據(當然還有XML註釋)生成的。必須有在文檔生成一個錯誤......

3

如果你看看IL拆卸,你可以看到,它確實有一個構造函數約束:如果文件是從直接生成

.class public sequential ansi serializable sealed beforefieldinit Nullable<valuetype (System.ValueType) .ctor T> 

程序集元數據,也許這是原因?

5

C#要求值類型具有默認的公共構造函數,但CLR不需要。

如果您定義了一種支持此類型的結構定義的語言(我相信C++/CLI允許這樣做),那麼調用它的時間就會不明確。