Verständnisfrage zu Generic
-
So wie ich das verstanden habe wird bei Generic die Spezialisierung auf den Typ erst zur Laufzeit vorgenommen, im Gegensatz zu Templates wo das schon beim Compilieren passiert.
Soweit richtig?
Nun heißt es hier(developer.com) das für Referenzen ein einziger spezialisierter Typ reicht, da ja alle Verweise(Referenzen) gleich groß sind:[...]However, the .NET runtime optimizes the case where the replaceable type parameters are reference types. Generally speaking, the .NET runtime can produce a single specialization of a generic type that can be reused for all specializations where the replaceable types are reference types. For example, when the runtime produces the specialization of List<System.String>, the resulting specialized type properly handles all possible reference types. Therefore, a subsequent specialization request for List<Employee>, where Employee is a reference type, can reuse the existing code for List<System.String>. After all, in both cases the code is simply manipulating a reference and all references are conceptually used the same way and occupy the same amount of space—unlike the case for value types. Using one shared type for all reference type specializations of a particular generic class or method reduces code bloat and working set.[...]
Das wollte ich natürlich überprüfen und schrieb mir folgenden Code:
using System; using System.Collections.Generic; namespace Generic_Reference { class A { } class B { } class Test<T> { static Test() { Console.WriteLine("static Test()"); } } class Program { static void Main(string[] args) { Test<A> TestInt = new Test<A>(); Test<B> TestBool = new Test<B>(); } } }
Die Ausgabe ist jedoch:
static Test() static Test()
Warum?
-
Warum hast Du etwas anderes erwartet?
Nur einmal die Ausgabe?
Simon
-
Jop nur einmal, da ja afaik der statische Konstruktor nur einmal vor benutzen der Klasse aufgerufen wird.
Nun wird er aber zweimal aufgerufen was zumindest für mich darauf schließen lässt das es auch zwei verschiedene Typen sind.
-
Hallo,
du unterliegst einem kleinen Denkfehler. Es geht darum dass der Code der generiert wird für ein Generic bei Referenztypparametern wiederverwendet werden kann. Das hat erstmal gar nichts mit irgendwelchen Klassen am Hut, sondern sagt nur aus, dass die Runtime dort immer den gleichen Code verwenden kann, da es ja immer Referenzen sind, egal welcher spezielle Typ. Aus Entwicklersicht wäre es natürlich fatal wenn, egal welche Spezialisierung ich hätte, es immer die gleiche Klasse wäre, dann bräuchte man ja keine Generics. Die Klassen sind natürlich vollkommen getrennt, alles ist typsicher wie gewohnt, es geht nur um den Code den die Runtime ausführen muss, und da spart man bei Referenztypen.
-
Das eine ist die technische Realisierung von Generics und das andere das andere das Verhalten (wie es die Sprach Sepzifikation vorschreibt) von Generics.
Das darf nicht verwechselt werden.
Die technischen Realisierung ist ein Impl. Detail.Simon