Предпочитаете Наследование или Сдерживание при создании специализированных коллекций? - PullRequest
2 голосов
/ 20 августа 2009

Мне нужны специализированные коллекции классов. Давайте назовем их FooItems и BarItems.

Мне в основном нужны все функции Списка, но мне нужно проделать дополнительную работу, когда новые элементы добавляются или удаляются из коллекции.

Моим первым достижением было просто извлечь из List и List, а затем создать мои собственные методы Add и Remove. Это, конечно, создает побочный эффект, скрывающий функцию, и компилятор предлагает использовать ключевое слово «new», чтобы явно скрыть базовые классы.

public class FooCollection : List<Foo>
{
    public new void Add(Foo foo)
    {
        // Do my work then...
        base.Add(foo);
    }
}

Хотя это воняет. Это может вызвать проблемы, если кто-то ссылается на коллекцию FooCollection через ссылку List или IList, поскольку она не будет вызывать мою (не виртуальную) функцию Add, а скорее версию List.

Конечно, в моем текущем коде это вряд ли произойдет ... но никто не может предсказать будущее.

Другой вариант, конечно, состоит в том, чтобы повторно реализовать Интерфейс IList и содержать Список, но воняет нарушением DRY (и это также много работы, особенно для нескольких коллекций).

Я уже склоняюсь к сдерживанию как предпочтительному методу ... просто интересно, есть ли у кого-нибудь еще какие-то комментарии по этому вопросу.

Ответы [ 2 ]

4 голосов
/ 20 августа 2009

Предпочитаю состав в этом случае.

Вы должны реализовать IList<T>, но никогда не выставлять List<T> напрямую (включая наследование) в каком-либо общедоступном API. Это должна быть деталь реализации.

3 голосов
/ 20 августа 2009

Я согласен с запахом и рекомендую сдерживание. Если вам нужна вся функциональность в IList<T>, вам, вероятно, не повезло в том, что касается простоты. Можете ли вы использовать, скажем, ICollection<T> вместо?

EDITED Если вам нужно сделать это несколько раз, вы всегда можете создать MyList<T> : IList<T> с виртуальными реализациями. По крайней мере, тогда вы реализуете большую часть интерфейса только один раз.

...