Lambda评估意外重新评估?

时间:2020-05-04 23:28:08

标签: c# lambda collections

对于lambda评估和lambda内联属性设置,肯定有些我不了解的地方。我有以下代码:

var zeroGroupings = ruleList.Rules.Where(r => r.DiagnosticGrouping == 0); // line 1
var oneGroupings = ruleList.Rules.Where(r => r.DiagnosticGrouping == 1); // line 2
var twoGroupings = ruleList.Rules.Where(r => r.DiagnosticGrouping == 2); // line 3

zeroGroupings.ForEach(r => r.DiagnosticGrouping = 1); // line 4
oneGroupings.ForEach(r => r.DiagnosticGrouping = 2); // line 5
twoGroupings.ForEach(r => r.DiagnosticGrouping = 3); // line 6

注释:ruleList.RulesIEnumerable个对象的集合(Rule)。保持简单和最小化,我认为除了ruleList对象具有名为ruleList.Rules的属性之外,没有人需要对RuleDiagnosticGrouping也不了解。 / p>

采取这种情况:

假设一个ruleList.Rules包含2个Rule对象,并且它们的DiagnosticGrouping均为0。第1-4行按预期执行。

zeroGroupings has a count of 2. 
oneGroupings has a count of 0.
twoGroupings has a count of 0.

全部符合预期。

在执行第4行之后,我的2个Rule对象的DiagnosticGrouping都为1。但是,在执行第5行之后,这2个Rule对象的DiagnosticGrouping突然变为2。在执行第6行之后,两个规则对象的DiagnosticGrouping现在都为3。

我希望在这种情况下,第5行和第6行不会匹配任何内容,因此不会执行任何操作。似乎第2行和第3行以某种方式在第5行和第6行中被重新评估,因此匹配,因此再次设置了属性。我不明白。

我需要做什么才能使所有操作按预期执行?

1 个答案:

答案 0 :(得分:2)

Where是一个延迟执行查询。它不会立即求值并填充集合。相反,它会在本身迭代时执行-扫描原始源以查找匹配项。每次迭代时都会执行此操作。造成这种情况的原因包括可组合性和内存使用情况。实际上,不仅源数据可以在查询创建和迭代之间更改,而且由于“捕获的变量”的工作方式,过滤器本身也可以在这一次之间更改!

基本上:如果要立即将其执行到列表中,请在.ToList()之后添加Where(...)

var zeroGroupings = ruleList.Rules.Where(r => r.DiagnosticGrouping == 0).ToList();