IEnumerable <T> .Reverse是如何工作的?

Joa*_*nge 21 .net c# linq collections

我正在检查反射器中的代码,但我还没有发现它如何通过集合向后枚举?

由于没有计数信息,枚举总是从集合的"开始"开始,对吧?

这是.NET框架中的缺点吗?成本是否高于常规枚举?

Mar*_*ell 43

简而言之,它会缓冲所有内容,然后向后穿过它.效率不高,但从那个角度来看,OrderBy也不是.

在LINQ-to-Objects中,有缓冲操作(Reverse,OrderBy,GroupBy等)和非缓冲操作(Where,Take,Skip等).


作为使用非缓冲Reverse实现的示例IList<T>,请考虑:

public static IEnumerable<T> Reverse<T>(this IList<T> list) {
    for (int i = list.Count - 1; i >= 0; i--) {
        yield return list[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果在迭代时改变列表,这仍然有点容易受到错误...所以不要这样做;-p

  • 确切地说,是的. (3认同)

Lev*_*evi 6

它的工作原理是将底层的IEnumerable <T>复制到一个数组,然后向后枚举该数组. 如果底层的IEnumerable <T>实现ICollection <T>(如T [],List <T>等),则跳过复制步骤,枚举器直接迭代底层集合.

有关更多信息,请查看Reflector中的System.Linq.Buffer <TElement>.

编辑:始终复制基础集合,即使它是ICollection <TElement>.这可以防止底层集合中的更改被Buffer <TElement>传播.