【发布时间】:2012-12-18 02:44:36
【问题描述】:
我对如何解析非虚拟方法的理解(在 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
这对我来说没有意义,我相信会让很多人陷入困境。如果您现在将变量车辆声明为 VehicleBase 类型,您将得到
Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
VehicleBase.Accelerate
这也是我在前一种情况下所期望的,因为方法 Accelerate 是非虚拟的。
在前面的输出中,(变量车辆类型为 Sedan,我希望调用 Sedan.Accelerate 而不是 VehicleBase.Accelerate。就目前而言,取决于您从哪里调用它(从内部班级或外部)行为正在改变。
在我看来,重新引入方法的重载解决规则优先,但我很难相信这是正确/预期的行为。
【问题讨论】:
-
不确定您在这里发现了什么令人困惑。你能解释一下你发现的问题吗?
-
我以为我做到了。已经提供了两个输出以及我的期望。我将编辑我的帖子以更清楚地解释我的期望
-
如果您在
VehicleBase中将Accelerate设为虚拟并在Sedan中覆盖它,您将获得您所期望的行为。 -
@juharr,这个问题的重点是方法 is 非虚拟的。所以我不想让它虚拟化。
-
@ShivKumar 你要么在虚拟环境中创建,要么得到你所看到的行为,就这么简单。 10 次中有 9 次在方法上使用新方法只是糟糕的设计。
标签: c# polymorphism overload-resolution