0

以下关于延迟执行的评论是否正确?

1. var x = dc.myTables.Select(r=>r);//yes
2. var x = dc.myTables.Where(..).Select(r=>new {..});//yes
3. var x = dc.myTables.Where(..).Select(r=>new MyCustomClass {..});//no

换句话说,我一直认为投影自定义类对象总是会导致急切执行。但我找不到支持/否认它的参考资料(尽管我看到的结果与它相矛盾,因此发表了这篇文章)

4

5 回答 5

7

您问题中的每个语句都是延迟执行的示例。Selectand语句的内容对Where结果值是否延迟执行没有影响。Select+Where语句本身决定了这一点 。

作为一个反例,考虑该Sum方法。无论输入是什么,这总是急切地执行。

var sum = dc.myTables.Sum(...);  // Always eager 
于 2013-03-15T15:53:44.207 回答
3

为了证明你的观点,你的测试应该是这样的:

var tracer = string.Empty;
Func<inType, outType> map = r => {
       tracer = "set";
       return new outType(...);
    } 

var x = dc.myTables.Where(..).Select(map);

// this confirms x was never enumerated as tracer would be "set".
Assert.AreEqual(string.Empty, tracer);
// confirm that it would have enumerated if it could
CollectionAssert.IsNotEmpty(x);
于 2013-03-15T19:08:06.063 回答
2

据我观察,立即强制执行的唯一方法是强制迭代集合。我通过调用.ToArray()我的 LINQ 来做到这一点。

于 2013-03-15T15:53:53.397 回答
2

通常返回序列的方法使用延迟执行:

IEnumerable<X> ---> Select ---> IEnumerable<Y>

并且返回单个对象的方法不会:

IEnumerable<X> ---> First ---> Y

因此,像Where, Select, Take,和之类的方法使用延迟执行是因为它们可以,而像, ,和Skip之类的方法因为不能而不能。GroupByOrderByFirstSingleToListToArray

这里

于 2013-03-15T15:56:54.463 回答
2

.Select(...)总是被推迟。

当您使用 时IQueryable<T>,this 和其他延迟执行方法会构建一个表达式树,并且在迭代之前不会将其编译为实际的可执行表达式。也就是说,您需要:

  • 对投影的可枚举执行 for-each。
  • 调用一个在内部枚举可枚举的方法(即.Any(...), .Count(...), .ToList(...), ...)。
于 2013-03-15T15:59:45.063 回答