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替换,因此方法调用将具有静态(或者在一般的解析时间)被解析为“新”方法. 所以我的问题是:在C#中如何实现泛型?我不知道CIL字节码,但我知道Java字节码,所以我明白面向对象的CLI语言如何工作在一个低级别.随时在这个层面上解释. 除此之外,我认为C#泛型是这样实现的,因为与Java的类型擦除系统相比,每个人都总是调用C#“True Generic”中的通用系统. 解决方法
在GenericTest> .Get(T)中,C#编译器已经选择了该对象.GetHashCode应被调用(虚拟).没有办法可以解析为运行时的“新”GetHashCode方法(它将在方法表中具有自己的插槽,而不是覆盖object.GetHashCode的插槽).
来自Eric Lippert的What’s the difference,part one: Generics are not templates,问题解释(使用的设置略有不同,但是课程可以很好地适应您的场景):
以及您所需语义的解决方法:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |