LINQ方法执行序列

时间:2014-07-27 08:13:41

标签: c# .net linq clr

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

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

到目前为止,我已阅读有关WhereSelectSkipSkipWhileTakeTakeWhile方法的内容。 而且,我知道 Defferred Immediate 执行以及Iterator这些方法返回的内容。

  

延迟执行是执行模型的一种模式   CLR确保仅在需要时才提取值   基于IEnumerable的信息源。当任何Linq运营商   使用延迟执行,CLR封装相关的   信息,例如原始序列,谓词或选择器(如果   任何),进入迭代器,将在信息时使用   使用ToListmethod或从原始序列中提取   ForEachmethod或手动使用底层的GetEnumeratorand   在C#中使用MoveNext方法。

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

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();

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

TakeWhile()方法在符合Where语句中的条件时执行。但是,Take方法并非如此。

第一声明:

enter image description here enter image description here

第二声明:

enter image description here enter image description here

你可以解释一下为什么吗?

2 个答案:

答案 0 :(得分:5)

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

在使用TakeWhile的示例中,您有两个lambda表达式 - 一个用于Where,另一个用于TakeWhile。所以你可以闯入那些lambda表达式的

了解WhereTakeWhile方法本身只被称为一次非常重要 - 但它们返回的序列会评估为遇到的每个值传递给它们的委托

您可能需要查看我的Edulinq blog series,了解有关LINQ内部的更多详细信息。

答案 1 :(得分:1)

嗯,TakeWhile中的条件需要针对每个项目进行评估,就像Where一样,因此它会为每个项目调用每个项目。

Take(4)不需要针对每个项目进行评估,只需Where进行评估,因此在第二个项目中,每次只评估Where条件,(可能是四次) )。