LINQ方法执行序列

Far*_*yev 3 .net c# linq clr

我正在读一本关于高级C#的书.而且,现在我正在阅读这部分内容:

实现基于委托的语法的Linq查询方法的幕后操作.

到目前为止,我看了一下Where,Select,Skip,SkipWhile,Take,TakeWhile方法.并且,我知道DefferredImmediate执行以及Iterator由这些方法返回的s.

延迟执行是执行模型的模式,通过该模式,CLR确保仅在基于IEnumerable的信息源需要时才提取值.当任何Linq运算符使用延迟执行时,CLR将相关信息(例如原始序列,谓词或选择器(如果有))封装到迭代器中,当使用ToList方法从原始序列中提取信息时将使用该迭代器.或ForEachmethod或在C#中手动使用底层的GetEnumeratorand MoveNextmethods.

现在让我们看看这两个例子:

IList<int> series = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };

// First example
series.Where(x => x > 0).TakeWhile(x => x > 0).ToList();

// Second example
series.Where(x => x > 0).Take(4).ToList();
Run Code Online (Sandbox Code Playgroud)

当我提出断点并调试这两个语句时,我可以看到一个区别.

TakeWhile()当一个项满足Where语句中的条件时执行的方法.但是,Take方法并非如此.

第一个声明:

在此输入图像描述 在此输入图像描述

第二个声明:

在此输入图像描述 在此输入图像描述

你能解释一下为什么吗?

Jon*_*eet 5

你的意思并不完全清楚,但是如果你问为什么你在lambda表达式中遇到了一个断点TakeWhile,但是你没有在其中找到一个断点Take,那就是Take根本不接受委托 - 它只接受一个数.在找到要返回的值时,没有用户定义的代码要执行,因此没有可以命中的断点.

在你的例子中TakeWhile,你有两个lambda表达式 - 一个用于Where,一个用于TakeWhile.所以你可以闯入这些lambda表达式中的任何一个.

重要的是要理解WhereTakeWhile方法本身只被调用一次 - 但它们返回的序列会评估为它们遇到的每个值传递给它们的委托.

您可以查看我的Edulinq博客系列,了解有关LINQ内部的更多详细信息.