如何才能从继承的类中访问属性?

时间:2016-05-19 03:07:48

标签: c#

我创建了一个用户控件,我需要在读取属性Controls时返回一个由我指定的ControlCollection而不是基本属性Control.Controls

我这样做了,如果我读取CustomGroupBox.Controls它有效但是如果一个方法将控件作为参数(它接收任何类型的控件,如CustomGroupBox,Button,Panel等),尝试读取它获得的Control.Controls基础ControlCollection。

让我用代码解释我的问题

CustomGroupBox.cs

public partial class CustomGroupBox : UserControl
{
    Panel Panel1 = null;
    Panel Panel2 = null;
    bool UseBaseControls = true;

    public CustomGroupBox()
    {
        InitializeComponent();

        Panel1 = new Panel() { Name = "Panel1" };
        Panel2 = new Panel() { Name = "Panel2" };
        Controls.Add(Panel1);
        Controls.Add(Panel2);

        UseBaseControls = false;
    }

    public new ControlCollection Controls { get { return UseBaseControls ? base.Controls : Panel1.Controls; } }
}

Form1.cs的

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        CustomGroupBox Container = new CustomGroupBox();
        Container.Controls.Add(new Button());
        Container.Controls.Add(new Button());
        Container.Controls.Add(new Button());
        Container.Controls.Add(new Button());

        Control Parameter = Container;

        int i = Container.Controls.Count;               // i=4
        int j = Parameter.Controls.Count;               // j=2
    }
}

有谁知道我必须在CustomGroupBox.cs上更改,所以j = 4?

更新

我找不到解决方案,我试图实现像IContainerControl这样的interfaz,但它不起作用。

1 个答案:

答案 0 :(得分:1)

嗯,这里的主要问题是UserControl.Controls属性不是虚拟的,因此不能在派生的CustomGroupBox类中重写。换句话说,该物业的吸气剂没有vtable条目。

因此,任何将对象实例视为基类类型之一(UserControlControl等)并调用Controls属性的代码都将从基础获取结果类。

此处使用new关键字可以让您有效地向Controls类添加一个名为CustomGroupBox的全新属性,但该新属性实际上与该属性不同在基类中具有相同名称。那么,调用新属性的getter的唯一方法是通过一个强类型为CustomGroupBox的变量。

一种技巧是将Parameter中的Form1_Load变量“转发”到CustomGroupBox,但在更复杂的情况下,这可能并不总是适合您。

您可以编写如下代码:

Control Parameter = Container;

int j = ((Parameter as CustomGroupBox)?.Controls ?? Parameter.Controls).Count;

此代码将在调用Control属性getter之前尝试从CustomGroupBoxControls的安全upcast,如果{{Controls属性getter则返回到基类Parameter属性getter 1}}实际上不是CustomGroupBox