可枚举重复函数

13

我遇到了一个奇怪的问题。这里我复现了这个问题。

Random r = new Random();
List<int> x = new List<int> {1, 2, 3, 4, 5, 6};

var e = x.OrderBy(i => r.Next());
var list1 = e.ToList();
var list2 = e.ToList();

bool b = list1.SequenceEqual(list2);
Console.WriteLine(b); // prints false

直到现在,我以为 Linq 函数在调用时被执行。但是,在这个方法中,似乎在我调用 ToList 后,Linq 函数 OrderBy 再次执行了。为什么会这样?


5
请参考查询执行:"LINQ 查询在迭代查询变量时执行,而不是在创建查询变量时执行。这被称为延迟执行。" - Idle_Mind
@Idle_Mind 你应该要说这是关于延迟执行的说明文件。并不是每个LINQ方法都会在迭代时执行。 - Yuval Itzchakov
1个回答

19

您正在查看延迟执行。当您创建一个LINQ查询时,它基本上是一个蓝图,说明“在请求时,执行这些步骤来操作数据源”。这里的棘手部分是,这个请求只由一组不同的LINQ操作(.ToList()是其中之一)完成。

因此,当您首次调用e.ToList()时,它将随机化数据源,因为这就是蓝图要求做的。然后,如果您再次在这个相同的蓝图上调用.ToList(),它会从头开始再次随机化。

蓝图不包含任何状态,它只说出了每个步骤应该怎样进行。


5
准确来说:LINQ 尽可能使用延迟执行。对于 OrderByWhere,仅在被请求时(即通过调用 ToList)进行评估。而对于其他方法,例如 CountSum,则会立即执行。 - Daniel Rose
1
@DanielRose 基本上,只要可能,LINQ 就会使用延迟执行。例如,您可以在不迭代整个集合的情况下进行计数或求和。 - Yuval Itzchakov
3
@YuvalItzchakov,你不能在不迭代整个集合的情况下计数或求和;这是你的意思,对吗? - Martijn

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