2011-01-12 48 views
60

我有一個需要在數據庫上查詢的類型列表(System.Type)。C#使用System.Type作爲通用參數

對於每一個這種類型的,我需要調用以下extensionmethod(這是LinqToNhibernate的一部分):

Session.Linq<MyType>() 

但是我沒有MyType的,但我想用一個類型來代替。

我所擁有的是:

System.Type typeOne; 

但我不能執行以下操作:

Session.Linq<typeOne>() 

我如何使用類型爲泛型參數?

回答

70

你不能,直接。泛型的要點是提供編譯時間類型安全性,您可以在編譯時知道您感興趣的類型,並且可以使用該類型的實例。在你的情況下,你只知道Type,所以你不能得到任何編譯時檢查,你有任何對象是該類型的實例。

你需要通過反射調用的方法 - 是這樣的:

// Get the generic type definition 
MethodInfo method = typeof(Session).GetMethod("Linq", 
           BindingFlags.Public | BindingFlags.Static); 

// Build a method with the specific type argument you're interested in 
method = method.MakeGenericMethod(typeOne); 
// The "null" is because it's a static method 
method.Invoke(null, arguments); 

如果你需要使用這種類型很多,你可能會發現更方便地編寫它調用自己的泛型方法其他任何通用方法都需要,然後用反射電話您的方法。

+1

我讀到了一個使用反射調用方法的解決方案。但我希望有另一種解決方案。 – Jan 2011-01-12 11:04:19

22

要做到這一點,你需要使用反射:

typeof(Session).GetMethod("Linq").MakeGenericMethod(typeOne).Invoke(null, null); 

(假設Linq<T>()是類型Session一個靜態方法)

如果Session實際上是一個對象,你需要要知道Linq方法實際聲明的位置,並且傳入Session作爲參數:

typeof(DeclaringType).GetMethod("Linq").MakeGenericMethod(typeOne) 
    .Invoke(null, new object[] {Session});