我有一个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会发出警告,指出应该使用new
或override
关键字,因为我正在屏蔽用户控件上已有的成员。
在某种程度上,我使用面板来控制用户控件上的可见性的奇怪做法不是问题。在贡献者的帮助下,它显然是疯了,不应该这样做。但令我感兴趣的问题是override
和new
关键字的行为方式不同以及原因。
答案 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(它具有无限循环)因为你的二传手自称)。