繁体   English   中英

是否推迟执行

[英]deferred execution or not

以下有关DEFERRED EXECUTION的评论正确吗?

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

换句话说,我一直认为投射自定义类对象总是会引起渴望的执行。 但是我找不到支持/拒绝它的参考文献(尽管我看到的结果与之相矛盾,因此该帖子)

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

作为反例,请考虑Sum方法。 无论输入是什么,总是急切地执行此操作。

var sum = dc.myTables.Sum(...);  // Always eager 

为了证明您的观点,您的测试应如下所示:

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

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

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

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

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

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

因此,诸如WhereSelectTakeSkipGroupByOrderBy方法之所以会使用延迟执行,是因为它们可以这样做,而诸如FirstSingleToListToArray则不会,因为它们不能这样做。

这里

.Select(...)始终被延迟。

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

  • 对预计的可枚举进行逐项检查。
  • 调用内部枚举枚举(即一个方法.Any(...) .Count(...) .ToList(...) ,...)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM