不能使用開放式泛型類型的泛型類型參數,但是,你可以使用特定類型的S<T>
作爲參數:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : S<T>
在你的情況,如果該類型S
是完全在編譯時定義(封閉類型),您甚至不需要這樣做:
public static S<T> PerformOperationOnGenericArray<T>
(IList<T> myList, FunctionForGenericArray<T> operation)
應該足夠。
您只需要使用第一個表格,如果S
本身會有所不同。那麼我的意思是什麼呢。我們來看一個例子。如果您有:
class Foo<T> { }
你可以寫:
public static Foo<T> PerformOperationOnGenericArray<T>
(IList<T> myList, FunctionForGenericArray<T> operation)
但是,如果你有一些組相關的一般類型:
class Foo<T> { }
class Bar<T> : Foo<T> { }
class Baz<T> : Foo<T> { }
,你要允許調用者指定哪一個要使用,那麼你需要做出該方法的通用簽名的返回類型部分:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : Foo<T>
其中呼叫者現在需要指定的R
類型明確:
PerformOperationOnGenericArray<T,Bar<T>>(...)
如果你想允許被允許接受單個參數的任何泛型類型,還有你的運氣了。該型系統不提供一種方式來表達的限制:
allow any generic type that allows a single parameter, and enforce that parameter to be a T
你能做的最好的是定義一個衆所周知的接口,所有已知類型的符合(如IEnumerable<T>
,或者一個你手藝自己),並用其作爲通用約束的一部分:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : IEnumerable<T>
然而,在這種情況下,提供的類型都必須實現此接口。如果您正在尋找前者(您可以指定任何類型,只需匹配類型參數的數量),您正在尋找通用的duck typing(1) - C#不支持。
有關這方面的一個有趣的方面說明。創建一個通用方法,其類型不能由編譯器僅從方法的形式參數中推斷出來,這是要儘量避免的。當無法推斷參數時,呼叫者被強制指定所有類型參數 - 這會導致混淆和冗長的代碼。儘管有時候這些情況確實會出現,但如果可能的話,最好儘量避免它們。
(1) - C#確實支持單個組件內的匿名類型鴨打字如果類型的順序,類型和它們的成員的名稱相匹配 - 在其上的編譯器將假定它們是相同的類型。
感謝您的回覆。不幸的是我已經嘗試了你的第二個建議,編譯器不喜歡S.我得到「Unknown Entity'S'」 – 2010-08-24 16:08:50
@Ryan - 第二種形式要求'S'是一個實際的類型。它不是一個類型參數。如果'S'本身就是一個類型參數,那麼你**必須使用第一種形式。我會更新我的答案,使其更清楚。 – LBushkin 2010-08-24 16:11:47
啊..我錯了你在說什麼。現在有意義了,謝謝你的澄清。 這不是要生產的東西。只需查看委託函數的泛型類型的界限即可。 – 2010-08-24 16:17:47