2012-07-16 53 views
4

我有一個我得到的場景Class name as a string我只是想創建該類的通用List。我試過以下使用反射的通用列表

  Type _type = Type.GetType(className); 

      List<_type> list = new List<_type>(); 

但是iam geting error。我無法將這個_type作爲列表參數。如果有人知道請幫我

+2

你爲什麼要那樣做?我敢打賭你1000美元,你試圖做的事情是愚蠢的,會導致糟糕的設計。 – Euphoric 2012-07-16 17:51:49

+0

我會扔進另一個盛大。 – 2012-07-16 17:54:19

+0

這似乎是一種潛在的不良模式。你能提供一些關於這個打算解決的問題的更多細節嗎?爲什麼你的班級名字通過一個字符串?這是某種自定義序列化器的一部分嗎? – JamieSee 2012-07-16 17:57:27

回答

10

最近你可以得到:

Type listType = typeof(List<>).MakeGenericType(_type); 
IList list = (IList) Activator.CreateInstance(listType); 
+0

如果_type類在另一個類庫中,可能嗎? – Nithesh 2012-07-17 05:33:26

+0

只要'_type'正在引用它。 – 2012-07-17 06:10:48

0

不幸的是,這是不可能的,因爲泛型需要在編譯時知道。您正嘗試通過在運行時使它們爲已知來重新定義它。他們需要在編譯時知道的原因是編譯器可以驗證傳遞給它的所有變量都是有效的。 AFAIK,做你想做的事情需要徹底重寫泛型。

編譯時間檢查背後的主要原因是_type可以在運行時更改,然後在添加到List<T>時會有開銷,因爲JIT編譯器需要進行類型檢查。

什麼@MarkusJarderot說是最接近你可以使用接口而不是泛型。

2

反射發生在運行時,因爲對象的類型可以通過正在運行的程序更改爲任何東西。

另一方面,類型參數(泛型)僅供編譯器用來檢查類型安全性。

因此,使用反射指定類型參數是不可能的,因爲編譯器將不知道任何關於反射結果的信息。

1

如果您使用的是.NET 4,然後用dynamic可能會有幫助。在這種情況下,您將能夠使用通過非通用接口無法訪問的實例上的方法(如IList)。

例如,使用dynamic可以讓您調用列表,你可以不通過投做IListAddRanges方法:

Type _type = typeof(int); 
Type listType = typeof(List<>).MakeGenericType(_type); 
dynamic list = Activator.CreateInstance(listType); 

list.Add(1); 
list.AddRange(new int[] {0, 1, 2, 3}); 

但是,這種方法並不像幾乎一樣類型 - 因爲它在編譯時無法捕獲錯誤,因此可以安全地轉換爲非通用接口。