IEnumerable .Reverse是如何工作的?
我正在检查reflection器中的代码,但我还没有发现它如何通过一个集合向后枚举?
由于没有计数信息,枚举总是从集合的“开始”开始,对吧?
它是.NET框架中的缺点吗? 成本是否高于常规枚举?
简而言之,它会缓冲所有内容,然后向后遍历它。 效率不高,但从那个角度来看,OrderBy也不是。
在LINQ-to-Objects中,有缓冲操作(Reverse,OrderBy,GroupBy等)和非缓冲操作(Where,Take,Skip等)。
作为使用IList
的非缓冲Reverse
实现的示例,请考虑:
public static IEnumerable Reverse (this IList list) { for (int i = list.Count - 1; i >= 0; i--) { yield return list[i]; } }
请注意,如果在迭代时改变列表,这仍然有点容易受到错误…所以不要这样做;-p
它的工作原理是将底层IEnumerable 如果底层IEnumerable
有关更多信息,请查看Reflector中的System.Linq.Buffer
编辑:始终复制基础集合,即使它是ICollection
它将所有项目加载到内存中,然后逐步执行(向后)。 效率低得多。
编辑:Opps,为反向写了错误的测试,我为错误的答案道歉。 校正测试后它会缓冲(使用Reverse()返回的枚举)
看起来反向扩展方法仅在填充集合时有效。 使用收益率回报时,它不会做任何事情。
使用反向思想进入问题它必须缓冲它才能工作,发现它不能用于产量。 它只是通过它,不做任何事情。 下面是我的测试代码。
[TestMethod] public void loopTest() { var series = this.GetSeries(); series.Reverse(); foreach (var l in series) { Debug.WriteLine(l); } } private IEnumerable GetSeries() { var series = new List () { 1, 2, 3, 4 }; foreach (var entry in series) { Debug.WriteLine(entry); yield return entry; } }
反向根本不调用GetSeries函数,这个论坛中的所有缓冲区会话都是空洞的。