【问题标题】:C# inheritance and overriding base propertiesC# 继承和覆盖基本属性
【发布时间】:2009-05-13 13:53:01
【问题描述】:

我目前需要一个自定义的 ListViewItem 类 - 我们称之为 MyListViewItem。它需要与每个项目关联一些附加数据,并在 Checked 属性更改时执行一些操作。我尝试了几件事,但目前相关代码如下所示:

class MyListViewItem : ListViewItem {
    new public bool Checked {
        get {
            return base.Checked;
        }
        set {
            base.Checked = value;
            // do some other things here based on value
        }
    }
    public MyListViewItem(Object otherData) {
        // ...
    }
}

我遇到的问题是,当我单击 ListView 中项目的复选框时,我的 setter 永远不会被调用。有谁知道我做错了什么?我知道我可以使用父 ListView 的 ItemChecked 事件,但这似乎是一个不太干净的解决方案。 (另外我实际上并没有将 Object 传递给构造函数,但这部分在这里并不重要)。

【问题讨论】:

  • 好吧,如果有人感兴趣,我最终会处理我的数据与自定义数据的 getter/setter 中的 Checked 属性之间的交互。不知道为什么我以前没有想到这一点。

标签: c# inheritance properties


【解决方案1】:

它不起作用,因为“new”关键字不会覆盖它只是“隐藏”。

这意味着如果您在通过 MyListViewItem 的类型定义引用的对象实例上调用 Checked,您运行您的代码。然而,ListView 通过 ListViewItem 的类型定义引用该对象,因此不会调用您的“新”方法。

“新”是不是覆盖。更好的解决方案可能是在自定义列表视图中处理代码。真的没有那么丑。

【讨论】:

  • 这就是我目前在 list_ItemChecked 处理程序中所做的。我认为它不需要自定义 ListView,所以在我想对我的自定义项目数据做任何事情之前,我只会查看 base.Checked。谢谢。
【解决方案2】:

new 不是 override base 成员。它声明了一个同名的新方法。在 VB.NET 中称为Shadows

确实,new 除了关闭编译器警告之外什么都不做。您未声明为override 的成员(并且您只能在base 成员为virtualoverride 时这样做)将与base 成员的继承树完全无关。

【讨论】:

    【解决方案3】:

    假设ListViewItem.Checked属性是虚拟的,你需要覆盖它:

    public override bool Checked
    

    【讨论】:

    • 它不是虚拟的。我想我只需要做些别的事情。谢谢!
    【解决方案4】:

    ListViewItem.Checked 属性不是虚拟的(请参阅 MSDN 文档here),因此您将无法以这种方式覆盖它的行为。您必须使用事件或从 ListView 派生并覆盖 ListView.OnItemChecked 才能更改行为。

    【讨论】:

      【解决方案5】:

      与其创建您自己的自定义 ListViewItem,不如创建一个单独的类型来包含您的自定义数据,然后为每个 ListViewItem Tag 属性分配对自定义数据的引用?

      这是我已经使用了一段时间的模式,并且效果很好。至于检查项目时的自定义操作,只需在列表视图中处理相关事件即可。

      【讨论】: