Q1)我想知道调用s.Last()linq扩展方法是否像执行一样高效s[s.Length-1].我更喜欢第一个选项,但我不知道实现是否利用了当前类型.
Q2)这可能是另一个有趣的问题.linq扩展方法在使用时是否利用了类型,或者只是将对象看作是IEnumerable?
不,它不如直接索引那样有效,即O(1).我们可以在看到参考源为Enumerable.Last:
public static TSource Last<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
IList<TSource> list = source as IList<TSource>;
if (list != null) {
int count = list.Count;
if (count > 0) return list[count - 1];
}
else {
using (IEnumerator<TSource> e = source.GetEnumerator()) {
if (e.MoveNext()) {
TSource result;
do {
result = e.Current;
} while (e.MoveNext());
return result;
}
}
}
throw Error.NoElements();
}
Run Code Online (Sandbox Code Playgroud)
由于String没有实现IList<char>,它将转到使用枚举器的分支,要求检查所有字符,直到找到最后一个(即O(n)).
如您所见,在某些情况下,LINQ方法会考虑更有效的方式来访问各种接口提供的数据.其他的例子包括First,Count,和ElementAt.