属性上的C#new和override关键字之间的区别

时间:2012-10-31 16:29:08

标签: c# asp.net stack-overflow

我有一个ASP.NET用户控件,其中有一个我用来隐藏和显示内容的面板,即

<asp:Panel runat="server" ID=pnlContainer">
    <!-- Some fairly uninteresting content -->
</asp:Panel>

我有一个可见属性作为重载,即

    public override bool Visible 
    {
        get { return pnlContainer.Visible; }
        set { pnlContainer.Visible = value;  } 
    }

当我设置它时,我得到一个堆栈溢出异常但是当我将关键字更改为new时,即

    public new bool Visible 
    {
        get { return pnlContainer.Visible; }
        set { pnlContainer.Visible = value;  } 
    }

一切正常。为什么是这样?我想我对这些关键词的了解程度普遍不高,而且会在这里显示出来。

此外:

如果我没有打开任何关键字 - Visual Studio会发出警告,指出应该使用newoverride关键字,因为我正在屏蔽用户控件上已有的成员。

在某种程度上,我使用面板来控制用户控件上的可见性的奇怪做法不是问题。在贡献者的帮助下,它显然是疯了,不应该这样做。但令我感兴趣的问题是overridenew关键字的行为方式不同以及原因。

2 个答案:

答案 0 :(得分:6)

微软页面 Knowing When to Use Override and New Keywords (C# Programming Guide) 总结了差异。

查看那里指出的代码部分。它也列在下面:

public static void TestCars2()
{
    Car[] cars = new Car[3];
    cars[0] = new Car();
    cars[1] = new ConvertibleCar();
    cars[2] = new Minivan();
}

foreach (Car vehicle in cars)
{
    System.Console.WriteLine("Car object: " + vehicle.GetType());
    vehicle.DescribeCar();
    System.Console.WriteLine("----------");
}

同样的原则也适用于您的来源。 .NET框架将页面上的所有控件视为基本Control类的集合。 Control.Visible是一个虚拟财产。

这意味着:当ASP.NET框架为所有控件调用Control.Visible时,从源调用的唯一Control.Visible属性是标记为override的属性,这是什么人们通常会想到标准的多态性。否则,如果您将属性声明为new,则当ASP.NET框架调用Control.Visible时,您的属性将永远不会被调用。

因此,覆盖会导致堆栈溢出异常,因为您正在调用panel.Visible,这是递归调用自身多次。

答案 1 :(得分:0)

new关键字隐藏了一个继承的成员(有关示例,请参阅 Knowing When to Use Override and New Keywords (C# Programming Guide) )。

所以当你在这种情况下应用new时,在某个时刻,对象被引用作为它的基类,并且正在调用基类setter而不是你的派生类setter(它具有无限循环)因为你的二传手自称)。