我正在读一本关于高级C#的书。而且,现在我正在读这部分:
实现基于委托语法的Linq查询方法的幕后操作。
到目前为止,我已阅读有关Where
,Select
,Skip
,SkipWhile
,Take
,TakeWhile
方法的内容。
而且,我知道 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
方法并非如此。
第一声明:
第二声明:
你可以解释一下为什么吗?
答案 0 :(得分:5)
它不是完全清楚你的意思,但是如果你问为什么你在TakeWhile
中的lambda表达式中遇到了断点,但是你没有在{Take
内找到一个断点。 1}},只是Take
根本不接受委托 - 它只接受一个数字。在找到要返回的值时,没有用户定义的代码可以执行,因此没有可用的断点。
在使用TakeWhile
的示例中,您有两个lambda表达式 - 一个用于Where
,另一个用于TakeWhile
。所以你可以闯入那些lambda表达式的 。
了解Where
和TakeWhile
方法本身只被称为一次非常重要 - 但它们返回的序列会评估为遇到的每个值传递给它们的委托
您可能需要查看我的Edulinq blog series,了解有关LINQ内部的更多详细信息。
答案 1 :(得分:1)
嗯,TakeWhile
中的条件需要针对每个项目进行评估,就像Where
一样,因此它会为每个项目调用每个项目。
Take(4)
不需要针对每个项目进行评估,只需Where
进行评估,因此在第二个项目中,每次只评估Where
条件,(可能是四次) )。