2012-12-09 216 views
1

比方說,我有一個泛型類:使用泛型類型的超類的泛型方法?

public class MyGenericClass<T> { 
    ... 
} 

現在這個班級裏面,我想有一個方法可以讓我與其他一般的互動,這可能是通用型TT任何超類,例如:

public void DoSomething<T1>(List<T1> things) 
    where T : T1 // of course this won't compile 
{ 
    ... 
} 

你會如何做到這一點?

回答

5

你不能,我害怕。你能來最接近的將是具有在非通用類中的方法 - 可能的擴展方法:

public static MyGenericClassExtensions 
{ 
    public static void DoSomething<T, T1>(this MyGenericClass<T> @this, 
              List<T1> things) 
     where T : T1 
    { 
     ... 
    } 
} 

這很好,因爲它同時引入兩種類型的參數。

當然,一個替代方案是,以保持方法的實例方法中MyGenericClass<T>,沒有約束,並檢查在執行時該約束。這對於泛型的編譯時安全性和一般聲明性而言是不幸的,但它最終可能會爲你更好地工作。

+0

有趣的是,因爲約束'where T1:T'被允許。任何想法爲什麼OPs約束不被允許? –

+0

@mikez:是的--OP的約束在'T'上,它不是該方法的類型參數。在我的方法中,兩個類型約束同時引入,因此您可以基於另一個約束一個約束。 –

+0

+1嘿喬恩,謝謝你的回答。只是覺得你想要一個ping來看看我想出的替代答案。 –

0

@ JonSkeet的回答,一如既往,是上的標記,但我沒有找到另一種方式來做到這一點沒有在我的代碼引起的任何動盪。我創造了另一個泛型類和修改現有的類,如下所示:

public class MyGenericClass<T, TBase> 
    where T : TBase 
{ 
    public void DoSomething(List<TBase> things) 
    { 
    ... 
    } 
} 

public class MyGenericClass<T> : MyGenericClass<T, T> 
{ 
    ... 
} 

這樣,我得到了所需的功能,同時仍然保持向後兼容性,即使用原來的單式通用仍然會工作即所有現有的代碼。

+1

這是假設你只希望能夠爲任何給定的MyGenericClass實例調用一個'TBase'類型。目前尚不清楚這種限制是否可以接受。 –

+0

@JonSkeet - 真實,公平的點。如果你想允許任何基類,你的答案仍然會贏。 –