from n in numbers where n = 5 select n是numbers.Where(n => n == 5)的语法糖。因此,您正在使用LINQ表达式将数字列表过滤为等于5的数字。 然而,LINQ计算 lazy。这意味着numbers.Where(n => n == 5)(an IEnumerable)返回的对象 * 不是 * 等于5的数字列表。该列表仅在需要时创建,即当尝试访问 IEnumerable 的元素时。 ToList将这个IEnumerable的内容复制到一个列表中,这意味着必须立即计算表达式。
8条答案
按热度按时间inkz8wg91#
from n in numbers where n = 5 select n
是numbers.Where(n => n == 5)
的语法糖。因此,您正在使用LINQ表达式将数字列表过滤为等于5的数字。然而,LINQ计算 lazy。这意味着
numbers.Where(n => n == 5)
(an IEnumerable)返回的对象 * 不是 * 等于5的数字列表。该列表仅在需要时创建,即当尝试访问 IEnumerable 的元素时。ToList
将这个IEnumerable的内容复制到一个列表中,这意味着必须立即计算表达式。sc4hvdpw2#
方括号的作用是为解析器消除歧义,即
.ToList()
可能仅指n
。xmakbtuz3#
在LINQ中,默认情况下,所有查询都是延迟加载的。也就是说,在枚举集合之前,查询本身已被分析,但尚未运行。
ToList()强制枚举集合“numbers”,并运行查询。
piok6c0g4#
在我看来,这就像是一个用圆括号括起来的LINQ表达式,其结果将是
IEnumerable<int>
,后跟对IEnumerable<T>
扩展方法ToList<T>()
的调用。我认为在本例中,调用
ToList<T>
强制立即对表达式求值,基本上避免了对求值的任何惰性。Eric白色在**Lazy (and Eager) Evaluation with LINQ**上写了一篇好文章
wz8daaqr5#
它将从
IEnumerable<t>
转换为List<t>
t9eec4r06#
您可能会发现,如果将其更改为直接使用扩展方法,则更容易向不熟悉LINQ的人解释。
对于这样一个简单的案例,这一点变得更加明显。
oyxsuwqo7#
熟悉LINQ的人可能会纠正我,但我的理解是,LINQ表达式本身不一定要求值,直到您对它“执行某些操作”。所以如果你想立即计算它,那么你应该像这样调用ToList()。(这也会将它从IEnumerable转换为IList,而不仅仅是对其求值。)
当然,它被 Package 在圆括号中,以告诉编译器ToList()处理的内容的全部范围。
wsewodh28#
圆括号将表达式分组为逻辑原子值。
这类似于算术
1 + 1 * 2 = 4
否!(= 3)(1 + 1) * 2 = 4
YES!