Как реализованы C # Generics?
Я думал, что Generics в C # были реализованы так, что новый класс / метод / what-have-you был сгенерирован во время выполнения или во время компиляции, когда использовался новый универсальный тип, аналогично шаблонам 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, и, таким образом, вызов метода был бы статически (или во время общего разрешения) преобразован в «new» метод.
Итак, мой вопрос заключается в следующем:How are generics implemented in C#? Я не знаю байт-код CIL, но я знаю байт-код Java, поэтому я понимаю, как объектно-ориентированные языки CLI работают на низком уровне. Не стесняйтесь объяснять на этом уровне.
Кроме того, я думал, что дженерики C # были реализованы таким образом, потому что каждый всегда вызывает родовую систему в C # & quot; Истинные дженерики & quot; по сравнению с системой стирания типа Java.