Hier der erste Post einer Serie von kurzen Hilfen die man schnell nachschlagen kann falls man vor dem gleichen Problem steht wie ich stand. Ich hoffe das diese Erklärungen helfen, kurz und knackig die Lösung zu bringen die man sucht.
Aber nun zum Thema. Wenn man sich ein bisschen mit dem dynamischen Erzeugen von Type-Instanzen beschäftigt hat, kann man wie ein Kumpel und ich gestern vor der Frage stehen: “Wie bekommt man eigentlich den Type von Generics?”.
Das ist eigentlich ganz einfach. Man weiß, das man normale Typen z.b. über die Methode Type.GetType() bekommen kann, indem man den Namen angibt. Wenn man sich für eine Assembly alle Typen einmal anzeigen lässt, sieht man sofort das Generische Typen etwas anders geschrieben werden. Als Beispiel die System Liste:
“class List<T>” wird als Type-Name “List`1″ (bei Mono + “[T]“) dargestellt.
“List” ist der ganz normale Klassenname, das “`” bezeichnet den generischen Type und die “1″ in diesem Fall steht für die Anzahl an Typen, welche dieser Generic inne hat. Also wenn man z.b. das Dictionary nimmt, dann hat man dort eine 2 stehen, da es den Key und den Value gibt.
Bei Mono ist das “T” in den eckigen Klammern für den Typen welcher für den Generic benutzt wird und spiegelt dessen Name wieder. Wenn man Dictionary<Key, Value> hat, dann steht dort auch “[Key, Value]“.
Nun zum Erstellen der Instanz, wofür wir wie normal den Activator von C# benutzen werden und als Beispiel nochmal die System List erstellen.
Den “Basis-Typen” für den Generic holen wir ganz normal über Type.GetType(), allerdings lassen wir in Mono für den Namen die Typen in den eckigen Klammern weg. Also folgendermaßen: Type.GetType(“List`1″);
Nun müssen wir aber auch angeben, welche Typen das Generic benutzen soll. Dafür hat die Type Klasse eine Methode welche sich MakeGenericType nennt. Diese möchte als Parameter ein Array von Typen, welche logischerweise genau das repräsentieren, was wir haben wollen. Als Beispiel erstellen wir eine Liste von integers. In der kurzen Form sieht das dann so aus:
1 | Type generic = Type.GetType("List`1").MakeGenericType(new Type[] { typeof(int) }); |
Type generic = Type.GetType("List`1").MakeGenericType(new Type[] { typeof(int) });Damit haben wir auch schon unseren spezifizierten generischen Typen und können ihn wie gewohnt über den Activator erstellen:
1 | Activator.CreateInstance(generic); |
Activator.CreateInstance(generic);
Vielen Dank fürs lesen und ich freue mich immer über Kommentare und konstruktive Kritik