linq 我该如何解释这段代码?

ih99xse1  于 2023-09-28  发布在  其他
关注(0)|答案(8)|浏览(108)

在.net中,可以这样写:

(from n in numbers where n == 5 select n).ToList();

如果没有这些方括号,就不能调用ToList()方法。我如何向别人解释这行代码的作用(我只能说它预编译了查询,但我不知道这是否100%正确)。

inkz8wg9

inkz8wg91#

from n in numbers where n = 5 select nnumbers.Where(n => n == 5)的语法糖。因此,您正在使用LINQ表达式将数字列表过滤为等于5的数字。
然而,LINQ计算 lazy。这意味着numbers.Where(n => n == 5)(an IEnumerable)返回的对象 * 不是 * 等于5的数字列表。该列表仅在需要时创建,即当尝试访问 IEnumerable 的元素时。
ToList将这个IEnumerable的内容复制到一个列表中,这意味着必须立即计算表达式。

sc4hvdpw

sc4hvdpw2#

方括号的作用是为解析器消除歧义,即.ToList()可能仅指n

xmakbtuz

xmakbtuz3#

在LINQ中,默认情况下,所有查询都是延迟加载的。也就是说,在枚举集合之前,查询本身已被分析,但尚未运行。
ToList()强制枚举集合“numbers”,并运行查询。

piok6c0g

piok6c0g4#

在我看来,这就像是一个用圆括号括起来的LINQ表达式,其结果将是IEnumerable<int>,后跟对IEnumerable<T>扩展方法ToList<T>()的调用。
我认为在本例中,调用ToList<T>强制立即对表达式求值,基本上避免了对求值的任何惰性。
Eric白色在**Lazy (and Eager) Evaluation with LINQ**上写了一篇好文章

wz8daaqr

wz8daaqr5#

它将从IEnumerable<t>转换为List<t>

t9eec4r0

t9eec4r06#

您可能会发现,如果将其更改为直接使用扩展方法,则更容易向不熟悉LINQ的人解释。

numbers.Where(number => number == 5).ToList();

对于这样一个简单的案例,这一点变得更加明显。

oyxsuwqo

oyxsuwqo7#

熟悉LINQ的人可能会纠正我,但我的理解是,LINQ表达式本身不一定要求值,直到您对它“执行某些操作”。所以如果你想立即计算它,那么你应该像这样调用ToList()。(这也会将它从IEnumerable转换为IList,而不仅仅是对其求值。)
当然,它被 Package 在圆括号中,以告诉编译器ToList()处理的内容的全部范围。

wsewodh2

wsewodh28#

圆括号将表达式分组为逻辑原子值。
这类似于算术
1 + 1 * 2 = 4否!(= 3)
(1 + 1) * 2 = 4 YES!

相关问题