扩展方法ToList()返回一个List<TSource>.遵循相同的模式,ToDictionary()返回一个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);
}
Run Code Online (Sandbox Code Playgroud)
那么为什么这个方法将其返回值键入为接口的特定实现而不是接口本身呢?唯一的变化是返回类型.
我很好奇,因为IEnumerable<>扩展在签名上非常一致,除了这两种情况.我一直认为这有点奇怪.
此外,为了使事情更加混乱,州的文件ToLookup():
根据指定的键选择器函数从IEnumerable创建Lookup.
但是返回类型是ILookup<TKey, TElement>.
在Edulinq,Jon Skeet提到返回类型List<T>不是IList<T>,而是不进一步触及主题.
广泛的搜索没有得到答案,所以在这里我问你:
是否有任何设计决策背后没有键入返回值作为接口,还是只是偶然?