如何解释这段代码?

4
在.NET中,可以编写如下代码:
(from n in numbers where n == 5 select n).ToList();

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

8个回答

6

from n in numbers where n = 5 select n 实际上是 numbers.Where(n => n == 5) 的语法糖。因此,你使用 LINQ 表达式对数字列表进行筛选,仅保留等于 5 的数字。

然而,LINQ 是一种惰性求值的方式。这意味着由 numbers.Where (n => n == 5) 返回的对象(一个 IEnumerable)不是等于五的数字列表。只有在尝试访问 IEnumerable 的元素时才会创建该列表。

ToList 将此 IEnumerable 的内容复制到一个列表中,这意味着必须立即评估表达式。


5
方括号的作用是为了让解析器明确 .ToList() 可能只是指 n

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

Heinzi解释得比我更简洁。 - Peter J

1

如果你直接使用扩展方法,可能会更容易向不熟悉LINQ的人解释。

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

对于像这样的简单情况,这变得更加明显。


1

在我看来,这似乎是一个用括号包装的 LINQ 表达式,其结果将是 IEnumerable<int>,随后调用 IEnumerable<T> 扩展方法 ToList<T>()

我认为在这种情况下,调用 ToList<T> 强制表达式立即计算,从本质上放弃了任何惰性计算。

Eric White 在 使用 LINQ 进行延迟(和急切)求值的好文章


1

它将一个 IEnumerable<t> 转换为一个 List<t>


0

更熟悉LINQ的人可能会纠正我,但据我所知,LINQ表达式本身并不一定在您“执行”之前被计算。因此,如果您想立即评估它,那么您将像这样调用ToList()。(这也将其从IEnumerable转换为IList,而不仅仅是评估它。)

当然,它被括在括号中,以告诉编译器ToList()的完整范围。


0

括号将表达式分组成逻辑上的原子值。

这类似于算术运算

1 + 1 * 2 = 4 错误!(= 3)

(1 + 1) * 2 = 4 正确!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接