2011-01-11 10 views
34

Ist es möglich, ein generisches Objekt von einem reflektierten Typ in C# (.Net 2.0) zu erstellen?C# instanziieren generische Liste vom reflektierten Typ

void foobar(Type t){ 
    IList<t> newList = new List<t>(); //this doesn't work 
    //... 
} 

Der Typ, t, ist bis zur Laufzeit nicht bekannt.

+0

Was erwarten Sie mit einer Liste, die Sie nicht wissen, die Art der Kompilierung? – dtb

+1

Können Sie dies als generische Funktion schreiben, wie in 'void foobar () {IList newList = neue Liste (); } ' – Juliet

+1

Ich habe das Gefühl, dass dies ein Code-Geruch sein könnte, als Folge der Bewältigung eines größeren Problems in einer schlechten Art und Weise. –

Antwort

102

Versuchen Sie folgendes:

void foobar(Type t) 
{ 
    var listType = typeof(List<>); 
    var constructedListType = listType.MakeGenericType(t); 

    var instance = Activator.CreateInstance(constructedListType); 
} 

Nun, was mit instance zu tun? Da Sie die Art Ihrer Liste den Inhalt nicht kennen, wahrscheinlich das Beste, was würden Sie tun könnte instance als IList zu werfen, so dass Sie etwas anderes als nur ein object haben könnte: kann

// Now you have a list - it isn't strongly typed but at least you 
// can work with it and use it to some degree. 
var instance = (IList)Activator.CreateInstance(constructedListType); 
+6

+1 für 'typeof (List <>)', I hatte das vorher nicht gesehen. –

+0

existiert 'var' in .Net framework 2.0 ?! –

+0

@sprocketonline: 'var' ist ein C# 3-Feature. Wenn Sie also C# 2 verwenden, müssen Sie Ihre Variablen explizit deklarieren. –

0

Sie verwenden MakeGenericType für solche Operationen.

Dokumentation siehe here und here.

6
static void Main(string[] args) 
{ 
    IList list = foobar(typeof(string)); 
    list.Add("foo"); 
    list.Add("bar"); 
    foreach (string s in list) 
    Console.WriteLine(s); 
    Console.ReadKey(); 
} 

private static IList foobar(Type t) 
{ 
    var listType = typeof(List<>); 
    var constructedListType = listType.MakeGenericType(t); 
    var instance = Activator.CreateInstance(constructedListType); 
    return (IList)instance; 
} 
+0

+1 für die guten alten nicht generischen unterstützten Schnittstellen erinnern :) – leppie