Jak zaimplementowano C # Generics?

Pomyślałem, że Generics w C # zostały zaimplementowane tak, że nowa klasa / metoda / co-masz-została wygenerowana w czasie wykonywania lub w czasie kompilacji, gdy użyto nowego typu ogólnego, podobnego do szablonów C ++ (które I nigdy tak naprawdę nie zaglądałem i bardzo dobrze mogłem się mylić, o czym chętnie bym się zgodził).

Ale w moim kodowaniu wymyśliłem dokładny kontrprzykład:

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();
        }
    }
}

Obie te linie konsoli są drukowane.

Wiem, że faktycznym powodem tego jest to, że wirtualne wywołanie Object.GetHashCode () nie rozwiązuje się na Test.GetHashCode (), ponieważ metoda w teście jest oznaczona jako nowa, a nie zastąpiona. Dlatego wiem, że jeśli użyłem „override” zamiast „new” na Test.GetHashCode (), to powrót 0 polimorficznie nadpisałby metodę GetHashCode w obiekcie i nie byłoby to prawdą, ale zgodnie z moim (poprzednim) rozumieniem z generycznych C # nie miałoby to znaczenia, ponieważ każda instancja T zostałaby zastąpiona Testem, a zatem wywołanie metody byłoby statycznie (lub w ogólnym czasie rozwiązania) rozwiązane do „nowej” metody.

Więc moje pytanie brzmi:W jaki sposób generyczne są zaimplementowane w C #? Nie znam kodu bajtowego CIL, ale znam kod bajtowy Java, więc rozumiem, jak języki CLI zorientowane obiektowo działają na niskim poziomie. Wyjaśnij na tym poziomie.

Na marginesie, pomyślałem, że generics C # zostały zaimplementowane w ten sposób, ponieważ każdy zawsze nazywa ogólny system w C # „True Generics” w porównaniu z systemem kasowania typu Java.

questionAnswers(1)

yourAnswerToTheQuestion