如何确定是否需要使用“Call”或“Callvirt”调用方法?
解决方法
您可以逐个遵循这些简单的规则来确定您应该使用哪些:
>方法是静态的吗?然后使用电话.
>您在值类型上调用的类型是什么?然后使用电话. (如果值被装箱,则不适用 – 那么您实际上是在对象或某个界面上调用,而这些是引用类型.)
>您调用的方法是虚拟还是抽象?然后使用callvirt.
>您是通过接口引用调用该方法吗?然后使用callvirt.
>您调用的方法是否声明覆盖,但方法和声明类型都没有声明密封?然后使用callvirt.
在所有其他情况下,不需要虚拟调度,因此您可以使用呼叫 – 但您应该使用callvirt.原因如下:
在非虚方法上使用callvirt等同于调用,除非第一个参数为null.在这种情况下,callvirt会立即抛出NullReferenceException,而call则不会.这是有道理的,因为callvirt旨在用于需要虚拟方法调度的情况,如果没有可以进行vtable查找的对象,则无法进行虚拟方法调度.
请注意,即使不需要vtable查找,如果第一个参数为null,callvirt仍将抛出异常!
考虑到这些信息,对引用类型的所有非静态方法调用使用callvirt(如C#编译器所做的那样)可能更好,因为它会在调用站点立即导致NullReferenceException,而不是在以后使用它时(显式或隐式)方法内部.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。