2009-11-29 101 views
5

是否有可能限制泛型方法只接受特定類型的結構?C#泛型,約束特定結構

這是可行的,我相信:

string Add<T>(object value, T expiration) where T : struct; 

但這不是它出現:

string Add<T>(object value, T expiration) where T : Struct1, Struct2; 

注:結構我要限制它的日期時間或時間跨度,因此我有沒有控制他們。

感謝

回答

7

不,因爲結構是密封的(您不能創建ValueType的子類)。

相反,請考慮您的結構實現一個接口,然後使用它作爲一個約束,像這樣:

string Add<T>(object value, T expiration) where T : struct, IMyInterface

+0

我同意這應該通過接口來實現。這是接口的目的之一! – Henri 2009-11-29 11:46:32

+0

感謝您的回答 - 請您能解釋不能繼承此類型的意義嗎?將參數約束爲結構(值類型)似乎是可能的並且與您的陳述相矛盾。我希望將它限制爲DateTime或TimeSpan的結構,因此將它們封裝在一個接口中似乎是唯一的解決方案(或保留未泛化)。 – Ben 2009-11-29 11:54:29

+2

你不能在一個你不能控制的結構上強制一個新的接口('DateTime','TimeSpan'等等),所以不行:你不能這樣做。 – 2009-11-29 12:21:13

-3

我認爲兩者都不行,一個結構是不是一個有效的約束。用作約束的類型必須是接口,非密封或類型參數

+1

http://msdn.microsoft.com/en-us/library/d5x73970.aspx表示前者正常 – Ben 2009-11-29 11:48:57

+0

確實,除了類型之外還有其他約束:「new()」「struct」或「class」。 – 2009-11-29 12:22:12

5

我想到過載是這裏最好的選擇:

string Add(object value, MyStruct1 expiration) {...} 
string Add(object value, MyStruct2 expiration) {...} 

這更適合,因爲你不能繼承一個結構,因此你的例子中的只有可行T將是MyStruct1MyStruct2 - 可能還有具體的方法,那麼。

Re將泛型限制爲多個引用類型;不是真的 - 即使有,名稱「添加」表明您希望使用運營商支持,其中不在C#(3.0)中。

但是,在C#4.0中,dynamic可能是一個選項 - 這是鴨式打字的優化形式;你不會得到編譯器支持(驗證等),但它應該工作。你會投給dynamic方法:

string Add<T>(object value, T expiration) where T : struct { 
    dynamic valueDyn = value; 
    valueDyn += expiration; // or similar 
    // more code 
} 

(在.net 3.5)另一種選擇是使用Operator supportMiscUtil,使用Operator.AddOperator.AddAlternative

7

泛型的目的是使方法和類型是泛型,因此名稱。如果你只有兩個可能的類型參數,那就寫兩個方法。

還請記住,C#泛型不是C++模板。當你在一個類型參數上調用一個方法時,比方說,這個方法調用將會是完全相同的方法調用對於每個構造的類型參數。這是通用。它不是一個模板,編譯器編譯代碼兩次,三次,一千次,每個類型參數一個,併爲每個方法重新調用該方法調用的內容。

所以,即使你可能限制你的類型參數爲兩種類型,你會有什麼好處?你可以調用它們的方法是他們通過基類Object創建的方法。在這種情況下,你已經有了一個適用於所有對象的泛型方法,爲什麼要將它限制爲兩種類型?

+0

可以使用'void Foo (T x)其中T:I'代替'void Foo(I x)'幫助避免' T'是按值類型? [這是一個相關的問題](http://stackoverflow.com/q/31457682/335858)。 – dasblinkenlight 2015-07-16 15:08:52