Рекомендации по возврату коллекций родового интерфейса - PullRequest
0 голосов
/ 16 февраля 2012

Обычно я стараюсь следовать методологии, чтобы аргументы методов были как можно более универсальными, а типы возвращались настолько универсальными, насколько это необходимо, и столкнулись с проблемой, ответ на которую мне не слишком ясен.

У меня есть элемент управления, который работает со структурой, такой как:

IDictionary<string, IDictionary<string, IEnumerable<MyObject>>>

Так что, предоставляя два ключа, мы получаем коллекцию объектов обратно.Довольно просто.

У меня есть класс

ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>

, который является просто словарем только для чтения, так что любые методы IDictionary, которые изменят словарь, выдают NotSupportedException ();

Словарь, в котором работает элемент управления, выходит из MyObjectRepository, который возвращает

ReadOnlyDictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<MyObject>>>

Поэтому вопрос заключается в том, должен ли я обновить тип возвращаемого значения в моем хранилище, чтобы он возвращал

IDictionary<string, IDictionary<string, IEnumerable<MyObject>>>

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

Похоже, это делает его менее понятным в отношении возвращаемого типа.Кроме того, интерфейс определяет ReadOnlyDictionary в качестве возвращаемого типа, так что реализующие классы не могут возвращать словари, которые позволили бы модификацию.Такое ощущение, что если интерфейс возвращает коллекцию, которая должна быть только для чтения, то возвращаемый тип должен это отражать.Указывая общий тип возвращаемого значения IDictionary <...>, методы, которые используют интерфейс, могут пытаться изменить словарь только для запуска в NotSupportedException.

Любые предложения о том, как решить эту проблему, приветствуются!

ОБНОВЛЕНИЕ Как оказалось, настоящая проблема здесь - с коллекцией ReadOnlyCollection.Его просто следует заменить на IEnumerable, и он упрощает большую часть работы по преобразованию между различными типами возвращаемых значений.

См. ReadOnlyCollection или IEnumerable для предоставления коллекций элементов? и обратите внимание на ответ Джона Скита.Вот почему я люблю ТАК:)

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Я бы хотел определить интерфейсы: DoubleKeyLookup<out ValT> и, исходя из этого, DoubleKeyLookup<in KeyT1, in KeyT2, out ValT>.Первый будет иметь такие методы, как GetSequence(Object key1, Object key2);, TryGetSequence и GetSequenceOrEmpty (первый будет выдавать значение not-found; второй вернет null; третий вернет Enumerable<ValT>.Empty).Второй будет аналогичным, но с «ключевыми» параметрами указанных типов.Большинство потребителей, вероятно, будут использовать второе, но первое будет пригодно для использования, если кто-то захочет, например, посмотреть, есть ли конкретный Animal в словаре, где все ключи Cat.

1 голос
/ 16 февраля 2012

Самый простой и удобный для пользователя способ, который я могу придумать:

Поскольку ReadOnlyDictionary реализует IDictionary <,>, но выдает исключения для неподдерживаемых операций, я бы порекомендовал самый простой и читаемый способ возвратаReadOnlyDictionary <,> который вместо этого реализует IReadOnlyDictionary <,>.IReadOnlyDictionary <,> будет просто производным от IDictionary <,>, поскольку они функционально эквивалентны.

Имя «IReadonlyDictionary» в прототипе метода будет указывать вызывающей стороне, что методы, которые изменяют словарь, могут не работать.

Надеюсь, это поможет!

...