2012-10-18 22 views
4

一小時前,我問了一個問題:how can I write an extension method for Enum?-Nullable<Enum>
出奇我得到的回答告訴我,我可以寫擴展方法爲Enum,它可以用於所有枚舉和可空枚舉。如何可爲空<T>使用它的基礎值類型的擴展方法

很酷,它工作,但如何?

如果我理解正確,所有枚舉都從Enum派生,所以爲什麼我可以在每個枚舉中使用這個擴展方法。

但是...例如,ItemType?枚舉不是枚舉,它是Nullable<ItemType>,它不是從ItemTypeEnum派生而來的。
就像List<DataReader>不從DataReader獲得,因此不能使用DataReader方法,雖然DataReader是它的泛型類型

我知道Nullable<T>類型有很多「巫術」和語法糖,這是其中之一嗎?

+0

這只是一個步驟,但與List案例不同,這裏是從Nullable 到T的[顯式轉換](http://msdn.microsoft.com/zh-cn/library/ms131345.aspx) ,這必須幫助。 – Rawling

+0

'我知道Nullable 類型有很多「voodoo」和語法糖,這是他們中的一員嗎?'我知道這是所有用戶定義的運算符重載的情況。編譯器將爲每個操作數的可空/不可空的版本的所有排列創建操作符的版本。它必須爲擴展方法做同樣的事情,但我無法在語言規範中找到它。 – Servy

回答

5

擴展方法不要求/派生類/,他們只是需要轉換到存在(更具體地:一個隱式標識,參考或裝箱轉換;這是§7.6.5.2「擴展方法調用」)

Nullable<ItemType>System.Enum的轉化是裝箱轉換。與從Nullable<int>System.Object的轉換相同

如果您定義了自己的結構struct Test : IMyInterface {},將會有從Nullable<Test>IMyInterface的轉換。

如果可以爲空,則可從空值進行的裝箱轉換將返回空引用;並且否則將可空值的值框。有關詳細信息,請參閱C#規範中的第6.1.7節「裝箱轉換」。

1

將擴展方法轉換爲靜態方法,其中第一個參數是該方法被調用的變量。在Enum例子中,由於Enum是一個類(不是結構體),所以擴展方法可以接受enum的具體值(通常被歸結爲一個int),或者是null。因此它可以使用可空的枚舉。

相同的東西不會用於int? (可空)。如果爲int創建擴展方法,則無法在Nullable上調用它(它會告訴您「不能將實例參數類型Nullable轉換爲int)

2

它比編譯器魔術更類型系統的魔力。由於Enum是引用類型,這意味着您傳遞的任何值都將被裝箱(例如轉換爲引用)。

現在Nullable<T>在拳擊它會產生枯萎null如果它代表一個空值或內型(T)的裝箱值的CLR的特殊處理,但從來沒有一個盒裝Nullable<T>。當然,情況正好相反;拆箱到可空類型接受null參考。