gpt4 book ai didi

c# - 非虚方法解析——为什么会这样

转载 作者:行者123 更新时间:2023-12-02 22:19:43 25 4
gpt4 key购买 nike

我(在 C# 中)对如何解析非虚拟方法的理解是它取决于变量的类型(而不是实例的类型)。

看看下面的代码。

class Program
{
static void Main(string[] args)
{
Sedan vehicle = new Sedan();
vehicle.Drive();
vehicle.Accelerate();
}
}

abstract class VehicleBase
{
public void Drive()
{
ShiftIntoGear();
Accelerate();
Steer();
}

protected abstract void ShiftIntoGear();
protected abstract void Steer();

public void Accelerate()
{
Console.WriteLine("VehicleBase.Accelerate");
}
}

class Sedan : VehicleBase
{
protected override void ShiftIntoGear()
{
Console.WriteLine("Sedan.ShiftIntoGear");
}

protected override void Steer()
{
Console.WriteLine("Sedan.Steer");
}

public new void Accelerate()
{
Console.WriteLine("Sedan.Accelerate");
}
}

控制台窗口显示以下内容:

Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
Sedan.Accelerate

这对我来说没有意义,我相信会让很多人大吃一惊。如果您现在将变量 vehicle 声明为 VehicleBase 类型,您将获得

Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
VehicleBase.Accelerate

这也是我在前一个案例中所期望的,因为 Accelerate 方法是非虚拟的。

在之前的输出中,(变量 vehicle 类型为 Sedan,我希望调用 Sedan.Accelerate 而不是 VehicleBase.Accelerate。就像现在一样,取决于您从哪里调用它(从内部类或来自外部)行为正在改变。

在我看来,重新引入的方法的重载解析规则优先,但我很难相信这是正确/预期的行为。

最佳答案

所有这一切都非常合理 - 当您将车辆声明为 Sedan 时,对 Accelerate 的两次调用的解析方式不同:

  • 当从 Drive 方法调用 Accelerate 时,它不知道 中有一个 new 方法>Sedan,所以调用base的相应方法
  • 当从 Main 方法调用 Accelerate 时,编译器知道您正在调用 new 方法,因为它知道vehicle 变量的确切类型是 Sedan

另一方面,当从 Main 方法调用 Accelerate 时,变量被声明为 VehicleBase,编译器无法假定类型为 Sedan,因此它再次将 Accelerate 解析为基类的方法。

关于c# - 非虚方法解析——为什么会这样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13895737/

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