2010-10-08 4 views
7

Angenommen, ich habe eine Klasse, die bis zur Laufzeit unbekannt ist. Zur Laufzeit bekomme ich eine Referenz, x, Typ Typ Verweis auf Foo.GetType(). Nur mit x und List <>, kann ich eine Liste des Typs Foo erstellen?Wie instanziieren Sie die Liste <T>, aber T ist bis zur Laufzeit unbekannt?

Wie geht das?

+3

Anything stoping Sie einfach erstellen eine 'Liste '? – Flynn1179

+0

@ Flynn1179, lassen Sie mich sehen, wie Sie das bitte tun. – xport

+0

'Liste myList = neue Liste ();' – Flynn1179

Antwort

19
Type x = typeof(Foo); 
Type listType = typeof(List<>).MakeGenericType(x); 
object list = Activator.CreateInstance(listType); 

Natürlich können Sie nicht jede Art Sicherheit hier als die resultierende Liste erwarten sollte, ist, vom Typ object zur Kompilierzeit. Mit List<object> wäre praktischer, aber immer noch Typ Sicherheit, da der Typ Foo nur zur Laufzeit bekannt ist.

+0

Schön! Ihre Antwort deutet (richtigerweise) auch darauf hin, dass die Arbeit mit einer solchen Liste ziemlich typsicher ist. Man könnte natürlich "liste" als einen (nicht generischen) Typ "IList" oder "ICollection" (statt nur "object") deklarieren, begleitet von einer entsprechenden Umsetzung von "Activator.CreateInstance" Wert, so dass eine begrenzte Art der Arbeit mit "liste" als Sammlung möglich wird. – stakx

+2

Wenn Sie zur Laufzeit Typen erstellen, können Sie sicher sein, dass es keine Art der Kompilierungszeit gibt. – Frank

0

Etwas wie folgt aus:

Activator.CreateInstance (typeof (List <>) Makegenerictype (Typ).)

11

Sicher können Sie:

var fooList = Activator 
    .CreateInstance(typeof(List<>) 
    .MakeGenericType(Foo.GetType())); 

Das Problem hier ist, dass fooList ist vom Typ object, also müssten Sie es immer noch auf einen "verwendbaren" Typ umwandeln. Aber wie würde dieser Typ aussehen? Da eine Datenstruktur, die das Hinzufügen und Nachschlagen unterstützt, Objekte des Typs T (oder besser IList<>) nicht in T kovariant ist, können Sie keinen List<Foo> an einen List<IFoo> senden, wobei Foo: IFoo. Du könntest es zu IEnumerable<T> werfen, das in T kovariant ist.

Wenn Sie C# 4.0 verwenden, könnten Sie auch in Betracht ziehen fooList zu dynamic, so dass Sie es zumindest als Liste verwenden können (z. B. hinzufügen, suchen und Objekte entfernen).

all dies bedenkt, und die Tatsache, dass Sie haben keine Kompilierung-Typen Sicherheit, wenn ohnehin Typen zur Laufzeit erstellen, einfach ein List<object> verwendet, ist wahrscheinlich die beste/pragmatische Art und Weise in diesem Fall zu gehen.

Verwandte Themen