Коллекции и списки
Является ли довольно безопасным предположение, что следующий класс является нечетным представлением "понижения" (из-за отсутствия лучшего слова) поля частного класса?
public class AggregatedClass : ICollection<SingleClass>
{
List<SingleClass> _singleClassList;
// ...rest of code
}
Недавно я увидел "рабочий" пример этого, и он бросил меня на бит цикла. В чем смысл вышесказанного? Если List<T>
реализует ICollection<T>
, то не является ли это вышеперечисленным классом? У вас есть поле частного класса, которое type class является расширением его реализации родительского класса (ICollection<T>
).
Можно ли сказать, что приведенный выше пример не является отличным дизайном?
Ответы
Ответ 1
Это абстрагирует List<T>
как деталь реализации, и если это необходимо/необходимо, класс может теперь предоставить дополнительную логику в различных методах списка (Add/Remove и т.д.), отметив, что они не являются виртуальными в List-of- Т).
Если вы имеете в виду, что поле должно быть ICollection - ну, это зависит от класса! Он может использовать дополнительные методы List-of-T, или это может быть просто нерелевантная деталь реализации, которая была удобна для тех, кто написал класс, и не наносит никакого вреда, поскольку он все равно является приватным.
Ответ 2
Я бы сказал, что в этом нет ничего плохого. AggregatedClass
предоставляет контракт, который ICollection<SingleClass>
и как реализован этот контракт, представляет собой деталь реализации, не предназначенную для каламбура.
Если для примера класс был определен как:
public class AggregatedClass : List<SingleClass>
тогда я должен был бы сказать, что да, есть проблема с дизайном. Рекомендуется не раскрывать List<T>
в общедоступном API и вместо этого выставлять Collection<T>
, поскольку коллекция предоставляет виртуальные методы, такие как InsertItem
и ClearItems
, а список не предоставляет никаких виртуальных методов, которые могут позже будет использоваться для переопределения поведения в базовом классе.
Если вы не хотите специально наследовать от Collection<T>
, тогда реализация ICollection<T>
, как в приведенном вами примере, является другой подходящей альтернативой, которая также позволяет наследовать класс из другого базового класса.
Ответ 3
Это почти зависит от того, что AggregatedClass будет делать в ближайшем будущем: путем реализации ICollection с использованием частного поля разработчик может освободить AggregatedClass от другого.
Так как С# не допускает множественного наследования, это ценная вещь.
На мой взгляд, если класс является "главным образом" списком, я бы получил его непосредственно. В случае, когда мне нужно наследовать из другого класса, всегда можно реорганизовать класс так, как вы указали в своем вопросе.