gpt4 book ai didi

.NET CIL 调用还是 CallVirt?

转载 作者:太空狗 更新时间:2023-10-29 21:15:00 26 4
gpt4 key购买 nike

如何确定一个方法是否需要使用“Call”或“Callvirt”来调用?

最佳答案

您可以一一遵循这些简单的规则来确定您应该使用哪一个:

  • 方法是静态的吗?然后使用调用
  • 您正在调用的类型是值类型吗?然后使用调用。 (如果值被装箱,这适用——那么你实际上是在 object 或一些接口(interface)上调用,那些是引用类型。)
  • 您调用的方法是声明为virtual 还是abstract?然后使用callvirt
  • 您是通过接口(interface)引用调用该方法吗?然后使用callvirt
  • 您正在调用的方法是否声明为override,但方法和声明类型均未声明为sealed?然后使用callvirt

在所有其他情况下,不需要虚拟分派(dispatch),因此您可以使用call -- 但您应该使用callvirt。原因如下:

在非虚拟方法上使用 callvirt 等同于 call,除非第一个参数为 null。在这种情况下,callvirt 将立即抛出一个 NullReferenceException,而 call 则不会。这是有道理的,因为 callvirt 旨在用于需要虚拟方法分派(dispatch)的情况,如果您没有要在其上执行 vtable 的对象,则不能执行虚拟方法分派(dispatch)查找。

请注意,如果第一个参数为 null,即使不需要 vtable 查找,callvirt 仍会抛出异常!

考虑到此信息,对引用类型的所有非静态方法调用(如 C# 编译器所做的那样)使用 callvirt 可能更可取,因为它会立即导致 NullReferenceException在调用站点而不是稍后在方法内部使用(显式或隐式)this 时。

关于.NET CIL 调用还是 CallVirt?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4210359/

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