1

我有一个带有面板的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关键字,因为我正在屏蔽用户控件上已经存在的成员。

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

4

2 回答 2

6

Microsoft 页面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,您的属性将永远不会被调用。

因此,覆盖会导致堆栈溢出异常,因为您随后会调用 your panel.Visible,它会递归地多次调用自身。

于 2012-10-31T16:54:00.650 回答
0

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

因此,当您new在这种情况下应用时,在某些时候该对象被引用为其基类,并且基类设置器被调用而不是派生类设置器(它具有无限循环,因为您的设置器调用自身)。

于 2012-10-31T16:41:45.213 回答