如何摆脱虚拟表?密封类

Can*_*ax_ 9 c# oop inheritance sealed vtable

据我所知,让班级sealed摆脱VTable中的查找或我错了吗?如果我创建一个类sealed,这是否意味着类层次结构中的所有虚方法也都标记了sealed

例如:

public class A {
    protected virtual void M() { ........ }
    protected virtual void O() { ........ }
}

public sealed class B : A {
    // I guess I can make this private for sealed class
    private override void M() { ........ }
    // Is this method automatically sealed? In the meaning that it doesn't have to look in VTable and can be called directly?

    // Also what about O() can it be called directly too, without VTable?
}
Run Code Online (Sandbox Code Playgroud)

Rom*_*och 2

“我想我可以将其设为密封班级的私人”

您无法更改继承层次结构中的访问修饰符。这意味着如果方法public位于基类中,则无法在派生类中创建它privateinternal或。protected仅当您将方法声明为:时才可以更改修饰符new

private new void M() { ........ }
Run Code Online (Sandbox Code Playgroud)

据我所知,使类密封可以摆脱在 VTable 中的查找,还是我错了?

密封类在层次结构中位于最后,因为您不能从它继承。虚拟表可以与类一起使用sealed,以防此类sealed覆盖基类中的某些方法。

如果我将一个类密封,这是否意味着类层次结构中的所有虚拟方法也被标记为密封?

可以看到IL代码:

.method family hidebysig virtual            // method is not marked as sealed
    instance void M () cil managed 
{        
    .maxstack 8

    IL_0000: nop 
    IL_0001: ret value
}  
Run Code Online (Sandbox Code Playgroud)

方法未标记为sealed。即使您显式标记此方法,sealed您也会获得相同的 IL 代码。

另外,没有理由将方法标记为类sealed中的方法sealed。如果类是sealed你不能继承它的,那么你也不能继承它的方法。

关于虚拟表 - 如果方法被重写并且您从虚拟表中删除它,则您永远不能在继承层次结构中使用它,因此,没有理由重写方法并且永远不会在继承层次结构中使用它。