Wie werden C # -Generics implementiert?

Ich hatte gedacht, dass Generics in C # so implementiert wurden, dass eine neue Klasse / Methode / what-have-you generiert wurde, entweder zur Laufzeit oder zur Kompilierungszeit, wenn ein neuer generischer Typ verwendet wurde, ähnlich wie bei C ++ - Vorlagen (die ich hab noch nie reingeschaut und ich könnte mich sehr wohl irren, worüber ich gerne eine korrektur akzeptieren würde).

Aber in meiner Codierung habe ich mir ein genaues Gegenbeispiel ausgedacht:

static class Program {
    static void Main()
    {
        Test testVar = new Test();

        GenericTest<Test> genericTest = new GenericTest<Test>();
        int gen = genericTest.Get(testVar);

        RegularTest regTest = new RegularTest();
        int reg = regTest.Get(testVar);

        if (gen == ((object)testVar).GetHashCode())
        {
            Console.WriteLine("Got Object's hashcode from GenericTest!");
        }
        if (reg == testVar.GetHashCode())
        {
            Console.WriteLine("Got Test's hashcode from RegularTest!");
        }
    }

    class Test
    {
        public new int GetHashCode()
        {
            return 0;
        }
    }

    class GenericTest<T>
    {
        public int Get(T obj)
        {
            return obj.GetHashCode();
        }
    }

    class RegularTest
    {
        public int Get(Test obj)
        {
            return obj.GetHashCode();
        }
    }
}

Beide Konsolenzeilen werden gedruckt.

Ich weiß, dass der eigentliche Grund dafür ist, dass der virtuelle Aufruf von Object.GetHashCode () nicht in Test.GetHashCode () aufgelöst wird, da die Methode in Test als neu markiert ist und nicht überschrieben wird. Daher weiß ich, wenn ich "override" anstelle von "new" für Test.GetHashCode () verwendet habe, würde die Rückgabe von 0 die Methode GetHashCode in object polymorph überschreiben und dies wäre nicht wahr, aber nach meinem (vorherigen) Verständnis Bei C # -Generika wäre dies nicht von Bedeutung gewesen, da jede Instanz von T durch Test ersetzt worden wäre und daher der Methodenaufruf statisch (oder zur generischen Auflösungszeit) in die "neue" Methode aufgelöst worden wäre.

Meine Frage lautet also:Wie werden Generika in C # implementiert? Ich kenne keinen CIL-Bytecode, aber ich kenne Java-Bytecode, sodass ich verstehe, wie objektorientierte CLI-Sprachen auf einer niedrigen Ebene funktionieren. Fühlen Sie sich frei, auf dieser Ebene zu erklären.

Abgesehen davon dachte ich, dass C # -Generiken auf diese Weise implementiert wurden, da jeder das generische System in C # im Vergleich zum Typlöschsystem von Java immer als "True Generics" bezeichnet.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage