Наследование из списка<T>
Какой самый быстрый способ реализовать новый класс, который наследует от List<T>
?
class Animal {}
class Animals : List<Animal> {} // (1)
Одна проблема, с которой я столкнулся: просто выполнив (1), я обнаружил, что не получаю выгоду от наследования каких-либо конструкторов от List<T>
,
В конце концов, я бы хотел Animals
вести себя во многом как List<T>
(например, может быть построен, совместимость с Linq). Но кроме того, я также хотел бы иметь возможность добавлять свои собственные методы.
6 ответов
Если вы хотите создать открытую коллекцию животных, вы не должны наследовать от List<T>
и вместо этого унаследовать от Collection<T>
и использовать постфиксCollection
в названии класса. Пример:AnimalCollection : Collection<Animal>
,
Это подтверждается рекомендациями по разработке структуры, а именно:
НЕ используйте
ArrayList
,List<T>
,Hashtable
, или жеDictionary<K,V>
в публичных API. использованиеCollection<T>
,ReadOnlyCollection<T>
,KeyedCollection<K,T>
или подтипы CollectionBase. Обратите внимание, что универсальные коллекции поддерживаются только в Framework версии 2.0 и выше.
Конструкторы не наследуются вместе с классом. Вы должны переопределить желаемые конструкторы.
public class AnimalsCollection : List<Animal>
{
public AnimalsCollection(IEnumerable<Animal> animals) : base(animals) {}
}
Извлечение из List<T>
не рекомендуется. Прежде всего потому, что List никогда не был предназначен для расширения, но для производительности.
Если вы хотите создать свою собственную коллекцию, вы должны наследовать от Collection<T>
, В вашем случае это будет:
class Animals : Collection<Animal> {}
Имейте в виду, что наследование от List не настолько полнофункционально, как вам может понадобиться, многие члены не являются виртуальными, поэтому единственный способ охватить базовую реализацию состоит в том, чтобы скрыть это с помощью new
синтаксис (в отличие от override
).
Если вам нужно начать демонстрировать пользовательское поведение в стандартных действиях со списком, я бы реализовал все интерфейсы списков для типа, который просто использует внутренний список для фактического хранения.
Это сильно зависит от ваших конечных требований.
class Animals : List<Animal> {}
Кажется, лучший способ, потому что вы можете использовать его сразу после определения, как это.
Так что мой совет - это название ваших вопросов: Inherit List<T>
;-)
Не нужно наследовать от List
использовать синтаксис инициализации коллекции или использовать методы расширения Linq.
Просто реализовать IEnumerable
а также Add
метод.