Почему Dictionary<k,v>
в интерфейсах плохая идея?
Спасибо
Потому что даже если вы сделаете их только для чтения
или const
, это не помешает клиентам изменять содержимое словаря (без вашего обеспечения). То же самое относится к массивам и спискам в общедоступных интерфейсах.
Чтобы решить эту проблему, вы можете либо предоставить копию контейнера клиенту (как jk упомянул в его / ее комментарии), либо (было бы слишком дорого копировать весь контейнер) предоставить ему методы доступа, например getItem
и setItem
. Таким образом, вы сохраняете контроль над содержимым контейнера.
Вы говорите о том, чтобы разоблачить их как свойства?
Потому что параметр метода типа IDictionary
для заполнения некоторых вещей может быть очень полезен. Очень похоже на функции AddRange(IEnumerable
, используемые в списках и т. д.
Обратите внимание, что я использую интерфейс IDictionary
, а не конкретный класс...
Если вам нужны триггерные действия при изменении словаря или ограничить доступ к нему (например, запретить удаление), вы должны предоставить в своем интерфейсе методы, которые обертывают словарь. Более того, вы получите гибкость, если захотите заменить базовый контейнер, в этом случае словарь.
Список List <>
имеет приятную особенность: метод AsReadOnly ()
, который возвращает реализацию IList <>
, доступную только для чтения.
Во-первых, следует предпочесть раскрытие коллекций через их интерфейс по сравнению с конкретным типом, так как это помогает избежать раскрытия клиентам того, какой тип коллекции используется, и дает автору класса (реализатору интерфейса) свободу использовать любую коллекцию, которая лучше всего подходит для данных потребностей/ограничений. Например, я могу раскрыть IList из интерфейса, а затем, будучи реализатором класса, который реализует этот интерфейс, я могу свободно выбрать использование сортированного списка, мешка, набора или любой другой коллекции, наиболее подходящей для моих нужд.
Вопрос о том, следует ли вообще раскрывать коллекцию из интерфейса, является спорным - если List раскрывается из класса, и класс имеет строгие правила, определяющие, можно ли добавить элемент в коллекцию или нет, что мешает клиентам манипулировать коллекцией напрямую, обходя тем самым любую логику. В отличие от этого метод AddItem может гарантировать, что добавляются только правильные элементы.
В случае со словарем вы можете представить элементы как IEnumerable
и иметь метод find, который предложит нам возможность найти элемент, используя обычную механику поиска по словарю. В качестве альтернативы вы можете представить его как IDictionary и затем вернуть реализацию словаря, доступного только для чтения