通过 C# 从 CLR 引用,它在我看来就像call
会在运行时通过 CLR 搜索由基类型定义的方法。
然后
call
IL指令用于调用实例或虚拟方法,必须指定一个变量来引用一个对象。变量本身的类型指示哪个类型定义了 CLR 应该调用的方法。如果变量的类型没有定义方法,则检查基类型是否有匹配的方法。
和
调用非虚拟实例方法时,JIT 会定位与用于进行调用的变量类型相对应的类型对象。如果类型没有定义被调用的方法,JIT 会沿着类层次结构向 Object 查找此方法。它可以这样做,因为每个类型对象中都有一个引用其基本类型的字段。然后,JIT 在类型对象的方法表中找到引用被调用方法的条目。
但是,根据以下示例,似乎在编译时检查了方法继承:
class A
{
public void Foo() {}
}
class B : A {}
void Main()
{
new B().Foo();
}
IL_0000: newobj UserQuery+B..ctor
IL_0005: call UserQuery+A.Foo // Not B.Foo, resolved by C# complier.
我对么?
即使我这样做:
void Main()
{
B x = new B();
x.Foo();
}
IL_0000: newobj UserQuery+B..ctor
IL_0005: stloc.0 // x
IL_0006: ldloc.0 // x
IL_0007: callvirt UserQuery+A.Foo // Not B.Foo, resolved by C# complier.
更新:
现在我明白分辨率是静态的。
而且我相信JIT需要的变量类型其实就是元数据token指定的类。
重复警报
实际上,在描述非虚拟方法调用的内部时,它是 Richter 错误的重复吗?
很高兴有另一个人和我有同样问题的人。