Один пример общего случая:
public class Validator
{
// ...
public ReadOnlyCollection<InvalidContainer> ContainersUnderMinimum
{
get { return _containersUnderMinimum.AsReadOnly(); }
}
}
public class InvalidContainer
{
// ...
public int LowestVolume { get; set; }
}
Приведенный выше класс Validator принимает коллекцию других элементов в своем конструкторе, а затем добавляет недопустимые элементы во внутренний список. Каждый контейнер имеет много субконтейнеров (например, стойку с пробирками), и класс хочет найти самый низкий объем. Конструктор добавляет в список, когда элемент (труба) не найден, и обновляет существующий объект списка, когда элемент найден.
Проблема заключается в том, что Validator хочет возвращать коллекцию неизменяемых объектов только для чтения, но объекты (InvalidContainers) должны быть изменяемыми после построения, чтобы значения (по сути) могли накапливаться (*).
Рефакторинг для использования интерфейса (IInvalidContainer) вызывает головную боль, поскольку общие коллекции не могут быть преобразованы в коллекции базового типа.
Какие есть хорошие модели или методы для решения этой проблемы?
РЕДАКТИРОВАТЬ: Чтобы уточнить, намерение состоит в том, чтобы значение свойства (коллекция) было неизменным. Я понимаю, что ReadOnlyCollection обеспечивает неизменность только коллекции, а не элементов коллекции. Обычно я делаю предметы неизменяемыми, но я не могу в этом (и подобных) случаях. Однако я хочу, чтобы элементы мутировали только во время создания класса Validator. Предотвращение вызывающих абонентов от неразумного кастинга не является целью дизайна; цель состоит в том, чтобы избежать соблазнения вызывающих абонентов с помощью настраиваемого открытого свойства.
РЕДАКТИРОВАТЬ: изменил название для ясности.
РЕДАКТИРОВАТЬ: Вот реорганизованная версия (на основе предложений от Л.Бушкина и рекурсивный):
public IEnumerable<IInvalidContainer> ContainersUnderMinimum
{
get
{
return _containersUnderMinimum.Cast<IInvalidContainer>();
}
}