2012-03-25 96 views
6

我不希望我的List是固定類型。相反,我希望List的創建取決於變量的類型。此代碼不起作用:如何創建動態類型列表<T>

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.Generic; 
namespace ConsoleApplication3 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      string something = "Apple"; 

      Type type = something.GetType(); 

      List<type> list = null; 

      Console.ReadKey(); 

     } 
    } 
} 

任何人都可以告訴我爲了使其正常工作需要做出什麼改變嗎?我想創建list取決於變量的類型something

+3

你需要爲此使用反射。你不能使用靜態類型的變量。或者找到一種不同的方法。 – 2012-03-25 13:16:22

+1

你爲什麼想這樣做? – svick 2012-03-25 13:21:13

+0

「我想要類型安全,但我需要動態類型安全。」你能詳細說明一下嗎? – 2012-03-25 13:24:45

回答

27
string something = "Apple"; 
Type type = something.GetType(); 
Type listType = typeof(List<>).MakeGenericType(new [] { type }); 
IList list = (IList)Activator.CreateInstance(listType); 

這是如何創建靜態未知類型的列表。但請注意,您無法靜態提及列表的運行時類型。您必須使用非泛型類型或對象。

不知道更多關於你想完成什麼,這是你能做的最好的。

+1

酷!除了ver需要var。 – Jaggu 2012-03-25 13:20:48

+2

@Jaggu不,var'不會完全符合你的想法。它不會給你一個可變類型的'List ',因爲'var'是一個靜態類型構造。 – 2012-03-25 13:23:07

+0

這會執行列表操作的運行時類型檢查嗎?因此,如果您嘗試添加非Apple類型的東西,是否會發生運行時錯誤? – 2012-03-25 13:26:58

0

編譯器在編譯時必須知道泛型類型T.所以不,你不能這樣做。

5

我想要類型安全,但我需要動態類型安全。

如果你的意思是你想要運行時類型安全,你可以使用反射(見USR的答案)或dynamic創建List<T>,然後把它作爲非通用IList

使用dynamic,它會是這個樣子:

static List<T> CreateListByExample<T>(T obj) 
{ 
    return new List<T>(); 
} 

… 

object something = "Apple"; 

IList list = CreateListByExample((dynamic)something); 

list.Add(something); // OK 

list.Add(42);  // throws ArgumentException 
1

動態和反射都做工精細 - ,但對性能有負面影響 - 和丟失強類型,代碼設計/清晰度等
也就是說,你應該總是嘗試和解決事情的w/o它 - 如果可以的話,你的代碼允許它...
所以,和(注)根據(非常)在您的特定代碼,需求,
你也可以使用一個「竅門」,以「推斷」類型,並使其通用 ...

class Program 
{ 
    static void Main(string[] args) 
    { 
     string something = "Apple"; 
     int test = 5; 
     var list = something.GetList(); 
     var listint = test.GetList(); 
     Console.WriteLine(list.GetType()); 
    } 
} 
static class Extension 
{ 
    public static List<T> GetList<T>(this T value) 
    { 
     return new[] { value }.ToList(); 
    } 
} 

...即。如果你有一個變量的值,並在'輸入'通用上下文之前,你可以使用擴展(對此非常有幫助), ,並讓它推斷你的類型和列表類型
注意:這種'解決'不幸並不總是平移,當你的代碼'太動態'(我知道這不是'確切',但超出了範圍),如果它取決於反射誘導類型等。
即沒有一個清晰的解決方案,這只是一個例子,你需要把一些汗水放在它:),使它爲你工作 - 例如你可能需要一個包裝類型在這裏和那裏,很明顯這樣創建一個列表可能不是你想要的。