Метод расширения ToList()
возвращает a List<TSource>
. Следуя той же схеме, ToDictionary()
возвращает a Dictionary<TKey, TSource>
.
Мне любопытно, почему эти методы не вводят возвращаемые значения как IList<TSource>
и IDictionary<TKey, TSource>
соответственно. Это кажется еще более странным, потому что ToLookup<TSource, TKey>
выводит возвращаемое значение как интерфейс вместо фактической реализации.
Рассматривая источник этих методов расширения с помощью dotPeek или другого декомпилятора, мы видим следующую реализацию (показывая ToList()
, потому что она короче):
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return new List<TSource>(source);
}
Итак, почему этот метод определяет его возвращаемое значение как конкретную реализацию интерфейса, а не самого интерфейса? Единственным изменением будет тип возврата.
Мне любопытно, потому что расширения IEnumerable<>
очень согласованы в своих подписях, за исключением этих двух случаев. Я всегда думал, что это немного странно.
Кроме того, чтобы сделать вещи еще более запутанными, документация для ToLookup()
гласит:
Создает поиск из IEnumerable в соответствии с указанная функция выбора ключа.
но возвращаемый тип ILookup<TKey, TElement>
.
В Edulinq Джон Скит упоминает, что тип возврата List<T>
вместо IList<T>
, но не касается темы далее.
Обширный поиск не дал ответа, поэтому я прошу вас:
Есть ли какое-либо конструкторское решение, не набирающее возвращаемые значения в качестве интерфейсов, или это просто случайность?