为什么 foreach 不调用 child class' 的新方法?

Why does foreach not call child class' new method?

我很惊讶地看到以下 C# 控制台应用程序的输出:

abstract class Shape
{
    public abstract void Draw();
}
class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing Circle");
    }
}
class SpecialCircle : Circle
{
    public new void Draw()
    {
        Console.WriteLine("Drawing SpecialCircle");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Shape[] myShapes = { new Circle(), new SpecialCircle() };
        foreach(Shape s in myShapes)
        {
            Console.WriteLine(s.GetType());
            s.Draw();
        }
        SpecialCircle scirc = new SpecialCircle();
        scirc.Draw();
    }
}

输出为:

CallChildClassMethod.Circle
Drawing Circle
CallChildClassMethod.SpecialCircle
Drawing Circle
Drawing SpecialCircle
Press any key to continue . . .

所以我想知道为什么在 foreach 语句中它识别数组的第二个元素是 SpecialCircle,却使用 class [=] 中的方法 Draw 15=]。与在数组和 foreach 循环之外定义 SpecialCircle 对象时的行为相反。

谁能帮我解决这个问题?

使用 new 时,您必须通过对 SpecialCircle class.

的引用来调用它

当您在循环外部调用时,您有一个对 SpecialCircle 的引用,这会导致调用 new 方法。

那是因为您正在使用 new 关键字,如果将其更改为 override,您将获得预期的行为。

new 不会覆盖基础 class 中的实现,而是隐藏它。这基本上意味着当实例被视为基础时,将调用基础实现,而当它被视为派生类型时,将调用派生类型实现。

你可以通过

来测试这个
SpecialCircle scirc = new SpecialCircle();
scirc.Draw();
Circle circle = scirc;
circle.Draw();

这将输出

Drawing SpecialCircle
Drawing Circle