string s [s.Length-1] vs s.Last()

rar*_*dev 2 c# linq string

Q1)我想知道调用s.Last()linq扩展方法是否像执行一样高效s[s.Length-1].我更喜欢第一个选项,但我不知道实现是否利用了当前类型.

Q2)这可能是另一个有趣的问题.linq扩展方法在使用时是否利用了类型,或者只是将对象看作是IEnumerable

Mik*_*ray 6

不,它不如直接索引那样有效,即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.