我曾經想過,C#中的泛型被實現,以便在運行時或編譯時生成一個新的類/方法/你什麼時候使用過新的泛型類型,類似於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()上使用「override」而不是「new」,那麼0的返回將多態地覆蓋對象中的方法GetHashCode,這不是真的,但根據我(以前)的理解的C#泛型不重要,因爲T的每個實例都將被替換爲Test,因此方法調用將靜態地(或在通用的解析時間)解析爲「new」方法。
所以我的問題是這樣的:如何泛型在C#中實現?我不知道CIL字節碼,但我知道Java字節碼,所以我理解面向對象的CLI語言如何在低級別上工作。隨意在該級別解釋。另外,我認爲C#泛型是以這種方式實現的,因爲與Java的類型擦除系統相比,每個人都總是用C#「True Generics」調用通用系統。
任何原因轉換爲對象在這裏'gen ==((object)testVar).GetHashCode()'? – AlwaysAProgrammer 2012-07-11 16:11:21
雖然它不直接回答你的問題,但http://blogs.msdn.com/b/ericlippert/archive/2012/07/10/when-is-a-cast-not-a-cast.aspx有一些好的有關泛型如何投射以及它們在C#中如何相互關聯的信息。 – devstruck 2012-07-11 16:11:40
@Yogendra這樣做訪問Object.GetHashCode()方法而不是「new」方法Test.GetHashCode()。這就是爲什麼它返回一個不同的值(因爲它完全運行一個不同的方法)。 – Carrotman42 2012-07-11 16:19:07