Как реализованы C #Generics?

Я думал, что Generics в C #были реализованы таким образом, что новый класс/метод/что -у вас -генерировалось либо во время выполнения -, либо во время компиляции -, когда новый универсальный использовался тип, аналогичный шаблонам C++ (, которые я никогда не изучал, и я вполне мог ошибаться, в отношении чего я бы с радостью принял исправление ).

Но в своем коде я придумал точный контрпример:

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

Обе эти строки консоли печатаются.

Я знаю, что на самом деле это происходит потому, что виртуальный вызов Object.GetHashCode ()не разрешается в Test.GetHashCode (), потому что метод в Test помечен как новый, а не переопределенный. Поэтому я знаю, что если бы я использовал «переопределить», а не «новый» в Test.GetHashCode (), то возврат 0 полиморфно переопределил бы метод GetHashCode в объекте, и это было бы неверно, но согласно моему (прежнее )понимание C #обобщений это не имело бы значения, потому что каждый экземпляр T был бы заменен на Test, и, таким образом, вызов метода был бы разрешен статически (или во время разрешения обобщения )к «новому» методу.

Итак, мой вопрос таков:Как дженерики реализованы в C #? Я не знаю байт-код CIL, но я знаю байт-код Java, поэтому я понимаю, как языки CLI, ориентированные на объект -, работают на низком уровне. Не стесняйтесь объяснять на этом уровне.

Кроме того, я думал, что дженерики C #были реализованы таким образом, потому что все всегда называют универсальную систему в C #«истинными дженериками» по сравнению с системой стирания типа -в Java.

11
задан Carrotman42 11 July 2012 в 16:06
поделиться