Myślałem, że Generics w C# zostały zaimplementowane w taki sposób, że nowa klasa/metoda/what-have-you została wygenerowana, albo w czasie wykonywania, albo podczas kompilacji, kiedy użyto nowego generycznego typu, podobnego do szablonów C++ (do którego nigdy nie zaglądałem i bardzo dobrze mogę się mylić, o co chętnie przyjmuję poprawki).W jaki sposób zaimplementowano C# Generics?
Ale w moim kodowania wymyśliłem dokładnego 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 druku.
Wiem, że faktycznym powodem tego jest to, że wirtualne wywołanie Object.GetHashCode() nie jest przetwarzane na Test.GetHashCode(), ponieważ metoda w teście jest oznaczona jako nowa zamiast przesłonięcia. Dlatego wiem, że jeśli użyłbym "override" zamiast "new" w Test.GetHashCode(), to powrót 0 przesłoni polimorficznie metodę GetHashCode w obiekcie i to nie będzie prawdą, ale zgodnie z moim (poprzednim) zrozumieniem generycznych C# nie miałoby znaczenia, ponieważ każda instancja T zostałaby zastąpiona przez Test, a zatem wywołanie metody miałoby statyczny (lub ogólny czas rozwiązania) został rozwiązany do "nowej" metody.
Moje pytanie brzmi następująco: W jaki sposób są realizowane generics 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. Możesz wyjaśnić na tym poziomie.
Odkładając na bok, myślałem, że generics C# zostało zaimplementowane w ten sposób, ponieważ każdy zawsze nazywa system ogólny w C# "True Generics" w porównaniu do systemu usuwania typu Java.
dowolny powód do rzucenia do obiektu tutaj "gen == ((obiekt) testVar) .GetHashCode()"? – AlwaysAProgrammer
Chociaż nie odpowiada bezpośrednio na twoje pytanie, http://blogs.msdn.com/b/ericlippert/archive/2012/07/10/when-is-a-cast-not-a-cast.aspx ma kilka dobrych informacje o tym, jak generics są rzutowane i jak odnoszą się do siebie w języku C#. – devstruck
@Yogendra Wykonuje to dostęp do metody Object.GetHashCode() zamiast "nowej" metody Test.GetHashCode(). Dlatego zwraca inną wartość (ponieważ całkowicie działa inna metoda). – Carrotman42