2010-08-24 190 views
2

我正在處理泛型委託函數並聲明List類型的返回類型。C#泛型類型的泛型對象實例化

public static List<T> PerformOperationOnGenericArray<T>(IList<T> myList, 
    FunctionForGenericArray<T> operation) 

我能夠用一個通用的返回類型,而不是名單中也指定了一個通用型差,即s

public static S<T> PerformOperationOnGenericArray<T, S>(IList<T> myList, 
    FunctionForGenericArray<T> operation) 

我猜,這是不可能的,但我看不到的原因至於爲什麼不。編譯器當然知道,當我指定類型:

PerformOperationOnGenericArray<int, List<string>>(myInts, i => i.Equals(12)); 

這也許是一個情況,即我需要看看使用動態類型?

回答

3

不能使用開放式泛型類型的泛型類型參數,但是,你可以使用特定類型的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#確實支持單個組件內的匿名類型鴨打字如果類型的順序,類型和它們的成員的名稱相匹配 - 在其上的編譯器將假定它們是相同的類型。

+0

感謝您的回覆。不幸的是我已經嘗試了你的第二個建議,編譯器不喜歡S.我得到「Unknown Entity'S'」 – 2010-08-24 16:08:50

+0

@Ryan - 第二種形式要求'S'是一個實際的類型。它不是一個類型參數。如果'S'本身就是一個類型參數,那麼你**必須使用第一種形式。我會更新我的答案,使其更清楚。 – LBushkin 2010-08-24 16:11:47

+0

啊..我錯了你在說什麼。現在有意義了,謝謝你的澄清。 這不是要生產的東西。只需查看委託函數的泛型類型的界限即可。 – 2010-08-24 16:17:47