本文介绍了才是硬道理用不同的名称法律的最终(IL)/密封(C#)的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类层次:

 类C1 {虚拟对象M1(); } 

类C2:C1 {覆盖密封对象M1(); }

级C3:C2 {
//我要重写M1()
// CSC给我一个错误,显然
改写对象M1();
}



但似乎有一种方法。在IL,您可以覆盖具有不同名称的方法。所以,我们改变名称( M1_2()覆盖 M1()),说它将覆盖方法的基础上,类( C1 :: M1())的一拉的显式接口实现,并在中间( C2 )类不再重要。

 的.class众汽车ANSI beforefieldinit N.C3 
扩展N.C2
{
。方法私人hidebysig虚拟决赛
实例对象M1_2()CIL管理
{
.override N.C1 :: M1

ILASM会很乐意进行组装,它显示了在ILSpy为

 公共类C3:C2 
{
对象C1.M1_2()

然后在同一个班级,你可以定义一个新M1 这就要求 this.M1_2 ()
所以,你有1)重写 M1 (使用不同的名称,但仍...)和2)有一个 M1 在C3的方法(这是一个桥梁,但它是你所看到的)。



但它看起来...错了。又或者是合法的吗?



如果你调用

  C1 OBJ =新C3(); 
obj.M1();



然后 M1_2 正确调用(我核实它在调试器)。看来,CLR强制只有链是直接的最后约束( C1 :: M1> C2 :: M1> C3 :: M1 ),而不是如果你做跳过层级( C1 :: M1> C3 :: M1_2 )。你必须选择一个不同的名字,虽然。如果您使用相同的名称(M1):

 的.class众汽车ANSI beforefieldinit N.C3 
扩展N. C2
{
。方法私人hidebysig虚拟决赛
实例对象M1()CIL管理
{
.override N.C1 :: M1

将无法正常工作,丢个 System.TypeLoadException





我想知道:那些CLR的规则,或者我刚刚发现在执行一个角落里呢? (在规则的一角情况下就可以了,在执行..你不能指望它;))


解决方案

相貌。像在规范中的边缘情况



在ECMA-335,分区第二节22.27 MethodImpl:



I wonder: are those CLR rules, or I just found a corner case in the implementation? (A corner case in the rules would be fine, in the implementation.. you cannot count on it ;) )

解决方案

Looks like an edge case in the specification.

In ECMA-335, Partition II section 22.27 MethodImpl:

So the specific method you try to override must not be sealed and must be defined on an ancestor class, but there is no requirement that the specific method specified is the most specific override for that slot in your ancestor chain.

Having said that, this is probably "sufficiently unexpected" that future versions may impose security restrictions to do this sort of thing.

这篇关于才是硬道理用不同的名称法律的最终(IL)/密封(C#)的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 22:57