[英]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
换句话说,我一直认为投射自定义类对象总是会引起渴望的执行。 但是我找不到支持/拒绝它的参考文献(尽管我看到的结果与之相矛盾,因此该帖子)
您问题中的每条陈述都是延迟执行的一个例子。 Select
和Where
语句的内容对是否推迟执行结果值没有影响。 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
因此,诸如Where
, Select
, Take
, Skip
, GroupBy
和OrderBy
方法之所以会使用延迟执行,是因为它们可以这样做,而诸如First
, Single
, ToList
和ToArray
则不会,因为它们不能这样做。
从这里
.Select(...)
始终被延迟。
当您使用IQueryable<T>
,此和其他延迟执行方法将构建一个表达式树,并且直到对其进行迭代之前,它都不会编译成实际的可执行表达式。 也就是说,您需要:
.Any(...)
.Count(...)
.ToList(...)
,...)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.