我在2006年学习了C#,并且最近试图回到它.我已经了解到他们在C#3.0中添加了一些名为LINQ Extensions的东西.现在我熟悉扩展方法,我只是在思考那些与IEnumerables相关的细节.
今天早些时候,我和我的一位同事正在讨论以下代码块是否相同:
List<int> integers;
IEnumerable<int> subResult = items.Where(i => IsPrime(i));
IEnumerable<int> orderedResult = subResult.OrderBy(i => i);
Run Code Online (Sandbox Code Playgroud)
与
List<int> integers;
IEnumerable<int> result = items.Where(i => IsPrime(i)).OrderBy(i => i);
Run Code Online (Sandbox Code Playgroud)
他告诉我最新的更有效率,因为扩展使用了它的来源后期查询.我不太清楚我明白他的意思,我想知道他是不对的.
他们是等同的.他们都使用懒惰评估/后期查询.
这意味着当.Where调用方法时,它不执行列表的任何实际枚举,它只是保持对它的输入的引用以及它将检查和存储这些引用的条件.当该GetEnumerator方法稍后被调用时.Where,就会.Where采取行动.
同样的事情.OrderBy.在.GetEnumerator调用之前,它实际上不会对列表进行枚举.
这些东西很难理解,但有一些非常好的方法来了解它.首先是写一个像你一样的简单例子,最好分成多行,用一个简单的for-each循环来迭代所有项目.调试代码并逐行执行.看看调试器如何跳转.一开始它很混乱,但经过几次,你就会明白懒惰的评估是如何运作的.
Jon Skeet还有一个用于可视化LINQ的精彩演示.