如何在没有覆盖的情况下向类添加属性?

时间:2012-03-26 20:54:55

标签: c# asp.net .net class c#-4.0

我正在尝试扩展TreeViewItem以添加属性。使其复杂化的是它具有“Items”属性,该属性是相同类类型的列表。添加属性将要求我覆盖我不想做的children属性。这是原始的TreeViewItem:

public class TreeViewItem : NavigationItem<TreeViewItem>, INavigationItemContainer<TreeViewItem>, ITreeViewItem
{
    public IList<TreeViewItem> Items { get; }
}

如何在不强制覆盖“Items”属性的情况下添加MyProperty。我不想重新创建的“Items”属性会发生很多事情。感谢您提供任何帮助或建议。

5 个答案:

答案 0 :(得分:3)

听起来您想要将Items属性替换为具有非常不同定义的属性。如果是,请使用new

public class MyItem : TreeViewItem {
  public new List<SomethingElse> Items { 
    get { ... }
  }
}

通常使用new被视为不良做法。在某些特定情况下,它是必要/有用的,但总的来说它不受欢迎。对于这种类型的行为,更具体命名的属性通常是一个很好的中间地带

答案 1 :(得分:2)

正如JaredPar建议的那样,您可以使用new IList<MyExtendedTreeViewItem> Items属性隐藏Items属性。这不会替换基类的Items属性,因此您必须同步它们。您可以通过实现(私有或内部)类来包装基类的项集合来实现此目的:

class ItemsWrapper : IList<MyExtendedTreeViewItem>
{
    private IList<TreeViewItem> _baseItems;

    public ItemsWrapper(IList<TreeViewItem> baseItems)
    {
        _baseItems = baseItems;
    }

    public void Add(MyExtendedTreeViewItem item)
    {
        _baseItems.Add(item);
    }

    // much of implementation omitted here for brevity

    public MyExtendedTreeViewItem this[int index]
    {
        get { return (MyExtendedTreeViewItem)_baseItems[index]; }
        set { _baseItems[index] = value; }
    }
}

class MyExtendedTreeViewItem : TreeViewItem
{
    private ItemsWrapper _items;

    public MyExtendedTreeViewItem()
    {
        _items = new ItemsWrapper(base.Items);
    }

    public new IList<MyExtendedTreeViewItem> Items { get { return _items; } }
}

这不是完全类型安全的,因为有人可以获得对基本Items属性的引用,然后向其添加TreeViewItem,并且转换为MyExtendedTreeViewItem会抛出异常。

答案 2 :(得分:1)

您可以使用扩展方法属性,如下所示:

public static class TreeViewItemExtensions
{
   public static object GetPropertyValue(this TreeViewItem tvi)
   {
   }
}

无需覆盖任何内容,并使用新方法“扩展”TreeViewItem

希望这有帮助。

答案 3 :(得分:0)

我认为您应该创建一个扩展方法,如此处所述 -

http://msdn.microsoft.com/en-us/library/bb383977.aspx

而不是覆盖TreeViewItem。

答案 4 :(得分:0)

您可以覆盖它并在顶部/底部调用base.Items,或者使用关键字“new”标记您的版本,这会导致仅在调用者明确知道该对象的时候才使用您的方法版本你的新班级类型。 这取决于你的需要,但前者更为常见。