这有点回到前面,所有可枚举都由(而不是支持,因为它是从外部提供的扩展方法)支持,ElementAt()
但只有一些是也支持的类型[]
,例如List<T>
或任何实现的类型IList<T>
。
Grouping
当然可以[]
很容易地实现,但是它必须始终这样做,因为 API 将是一个它必须继续保持的承诺,或者如果它确实破坏了它会破坏以旧方式编写的代码。
ElementAt()
采用测试和使用方法,如果有东西支持IList<T>
,它将使用[]
,否则它会计算适当的数量。由于您可以与任何序列一起计数,因此它可以支持任何可枚举。
碰巧Grouping
确实支持IList<T>
但作为显式接口,因此以下工作:
//Bad code for demonstration purpose, do not use:
((IList<int>)Enumerable.Range(0, 50).GroupBy(i => i / 5).First())[3]
但是因为它是明确的,所以如果在另一种方法中发现了优势,它不必继续支持它。
的测试和使用方法ElementAt
:
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
if (source == null) throw Error.ArgumentNull("source");
IList<TSource> list = source as IList<TSource>;
if (list != null) return list[index];
if (index < 0) throw Error.ArgumentOutOfRange("index");
using (IEnumerator<TSource> e = source.GetEnumerator())
{
while (true)
{
if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
if (index == 0) return e.Current;
index--;
}
}
}
因此,从中获得最优的 O(1) 行为,而不是 O(n) 行为,但不限Grouping
于做出设计者以后可能会后悔的承诺。