gpt4 book ai didi

c# - `CallVirt` 和 `New` 关键字

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

这个问题链接到How CLR calls methods correctly hidden by derived class when reference is stored in a base class variable?

在我的例子中,我使用的是 callvirt 指令,而不是 call

     class BaseClass
{
public void Write()
{
Method();
}

protected virtual void Method()
{
Console.WriteLine("Base - Method");
}
}

class DerivedClass : BaseClass
{
private new void Method()
{
Console.WriteLine("Derived - Method");
}
}

static void Main(string[] args)
{
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();

dc.Write();
bcdc.Write();

Console.ReadKey(true);
}

输出:

 Base - Method
Base - Method

Write方法的IL代码:

   .method public hidebysig instance void  Write() cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: callvirt instance void Private_override.Program/BaseClass::Method()
IL_0007: nop
IL_0008: ret
} // end of method BaseClass::Write

这里我不明白为什么要调用Base方法。

这里 CLR 使用 callvirt 指令,这意味着它将寻找调用变量类型,因为类型是 DerivedClass 并且 DerivedClass 隐藏BaseClass.Method 那么堆中DerivedClass的MethodTable中应该只有DerivedClass.Method。为什么调用 BaseClass.Methodcallvirt 是否在搜索方法时寻找特定的 override 标志?

最佳答案

因为您没有覆盖它。将 new 更改为 override ,它将按照您讨论的方式运行(您还必须将可访问性更改为 protected ,否则它不会编译)。 new 创建一个不相关 方法,它恰好共享一个名称 - 它不是基类中其他同名方法的多态树的一部分。

你不妨问:“为什么这不调用 CompletelyDifferentName() ?”

class BaseClass
{
public void Write()
{
Method();
}

protected virtual void Method()
{
Console.WriteLine("Base - Method");
}
}

class DerivedClass : BaseClass
{
private void CompletelyDifferentName()
{
Console.WriteLine("Derived - Method");
}
}

答案是一样的:CompletelyDifferentName 与名为Methodvirtual(多态)方法没有任何关系。好吧,new void Method() 也不是 - 这就是 new 的意思

关于c# - `CallVirt` 和 `New` 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18226425/

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