为什么foreach不会打电话给儿童班?新方法?

时间:2016-03-23 13:57:52

标签: c# arrays foreach polymorphism parent-child

我很惊讶在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,但却使用类Draw中的方法Circle。与在数组和foreach循环外定义SpecialCircle对象时的行为相反。

任何人都可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:4)

这是因为您使用的是new关键字,如果将其更改为override,您将获得所期望的行为。

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

您可以通过

进行测试
SpecialCircle scirc = new SpecialCircle();
scirc.Draw();
Circle circle = scirc;
circle.Draw();

这将输出

Drawing SpecialCircle
Drawing Circle

答案 1 :(得分:0)

使用new时,您必须通过对SpecialCircle类的引用来调用它。

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