Как добавить свойство в класс без переопределения? - PullRequest
0 голосов
/ 27 марта 2012

Я пытаюсь расширить TreeViewItem, чтобы добавить свойство.Что усложняет то, что у него есть свойство «Items», представляющее собой список того же типа класса.Добавление свойства потребует от меня переопределения свойства children, которое я не хочу делать.Вот оригинальный TreeViewItem:

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

Как добавить MyProperty без необходимости переопределять свойство «Items».Многое происходит со свойством «Items», которое я не хочу воссоздавать.Спасибо за любую помощь или совет.

Ответы [ 5 ]

3 голосов
/ 27 марта 2012

Звучит так, как будто вы хотите заменить свойство Items тем, у которого совсем другое определение.Если это так, тогда используйте new

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

. В общем, использование new считается плохой практикой.Есть конкретные случаи, когда это необходимо / полезно, но в целом это осуждается.Свойство с более конкретным именем часто является хорошим ориентиром для такого типа поведения

2 голосов
/ 27 марта 2012

Как предложил JaredPar, вы можете скрыть свойство Items с помощью свойства new IList<MyExtendedTreeViewItem> 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 вызовет исключение.

1 голос
/ 27 марта 2012

Вы можете использовать метод расширения и , а не свойство, например:

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

Нет необходимости что-либо переопределять, и вы «расширяете» свой TreeViewItem новым методом (-ами).

Надеюсь, это поможет.

0 голосов
/ 27 марта 2012

Либо вы переопределяете его и вызываете base.Items сверху / снизу, либо вы помечаете свою версию ключевым словом «new», что приводит к тому, что ваша версия метода будет использоваться только тогда, когда вызывающая сторона явно знает, что объект имеет ваш новый тип класса. Это зависит от ваших потребностей, но первое встречается гораздо чаще.

0 голосов
/ 27 марта 2012

Я думаю, вы должны создать метод расширения. Как объяснено здесь -

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

Вместо переопределения TreeViewItem.

...