为何LINQ未在可行时实现ICollection<T>等接口?
关于LINQ Select()未优化ICollection输入的疑问
List<int> GetLengths(ICollection<string> strings) => strings .Select(s => s.Length) .ToList();
如果Select()能检查输入集合是否实现了ICollection<T>,并且可以提前获取其长度,那它也可以返回ICollection<T>,这样ToList()就能预先初始化结果列表的容量。但当前实现是逐个添加值,会触发log(N)级别的多次存储扩容。LINQ没有采用这种实现方式,是否有特定原因?
更新:针对我的提议存在诸多疑问,以下是对该思路的几点说明:
- LINQ已经返回许多不同的
IEnumerable<T>实现,在我看来,添加一个额外实现接口的迭代器并无问题。 - 只读
ICollection<T>无需在内存中具体化,只需具备Count属性。我有一个ICollection<T>的极简实现示例,行为类似Enumerable.Repeat<T>(),只是通过委托生成每个元素。它会频繁抛出异常,官方的ReadOnlyCollection<T>也是如此。 List<T>(IEnumerable<T> collection)构造函数已经会检查集合是否实现了ICollection<T>,以便预先分配存储容量,这并未违反任何接口或约定。- 从架构角度来看,实现
IReadOnlyCollection<T>更为合理,但遗憾的是BCL本身经常忽略这一点,且List<T>构造函数并未对此进行检查。
内容的提问来源于stack exchange,提问作者Dmitry Fedorkov
相关产品推荐
相关产品推荐

