Почему Enumerable.ToLookup <> () возвращает ILookup <,>, а не Lookup <,>? - PullRequest
9 голосов
/ 03 октября 2010

В Lookup<,> есть один метод, которого нет в ILookup<,>:

public IEnumerable<TResult> ApplyResultSelector<TResult>(
    Func<TKey, IEnumerable<TElement>, TResult> resultSelector);

Почему тип возвращаемого значения Enumerable.ToLookup<>() объявлен равным ILookup<,>, несмотря на тот факт, что всегда кажется, что он возвращает экземпляр Lookup<,>? Если вместо этого тип возврата был объявлен как Lookup<,>, вышеуказанный метод мог бы использоваться без приведения.

1 Ответ

16 голосов
/ 03 октября 2010

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

Как вы указали, ToList и ToDictionary возвращают конкретные типы, а не интерфейсы. Возможно, причина этого в том, что ToList и ToDictionary предназначались для того, чтобы вернуть вам копию, которую вы можете изменить , если захотите. Поскольку интерфейсы IList и IDictionary не гарантируют, что они доступны для редактирования (что, возможно, было плохой идеей), дизайнеры решили вернуть конкретный тип.

Представьте себе гипотетический ToIList() метод. Если вызывается для массива, он может быть реализован так, чтобы возвращать вам копию массива, потому что массивы реализуют IList<T>. Тогда вы можете быть удивлены, узнав, что колл Add() бросает.

С другой стороны, ILookup является интерфейсом только для чтения, поэтому вышеприведенное не применимо. Следовательно, нет никакой причины , а не следовать лучшей практике, как в случае с ToList.

...