gpt4 book ai didi

c# - 为什么可以从同一方法的覆盖版本调用方法的基本版本

转载 作者:行者123 更新时间:2023-11-30 13:26:27 25 4
gpt4 key购买 nike

我很困惑为什么 C# 让我这样做:

基类

public virtual void OnResultExecuted(ResultExecutedContext filterContext)
{

}

派生类

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}

这段代码没有问题。但是当我要覆盖的方法是 base.OnResultExecuted 时,它是如何调用的?

最佳答案

为什么这是有用的是很明显的。 “如何?”不太明显,但也很有趣。

存储 .NET 代码的 MSIL 编码有两条方法调用指令:

  • 调用
  • callvirt

不同之处在于,当callvirt 与虚方法一起使用时,它不会调用指示的方法。相反,它将指示的方法映射到对象类的 vtable 中的一个槽,找到属于对象类的实际实现,并调用该版本。

(对于非虚拟方法,callvirt 只是添加一个空检查,然后直接调用指示的方法)。

call 指令不使用 vtable。它只是调用 MSIL 中命名的方法。当您在 C# 中使用 base 关键字时,编译器会生成一条 call 指令,以便使用基类提供的确切方法,而不是链接的覆盖方法虚表。

此行为是 documented on MSDN for the call opcode

It is valid to call a virtual method using call (rather than callvirt); this indicates that the method is to be resolved using the class specified by method rather than as specified dynamically from the object being invoked.

关于c# - 为什么可以从同一方法的覆盖版本调用方法的基本版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23136479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com