我曾经想过,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