对于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.Rules
是IEnumerable
个对象的集合(Rule
)。保持简单和最小化,我认为除了ruleList
对象具有名为ruleList.Rules
的属性之外,没有人需要对Rule
或DiagnosticGrouping
也不了解。 / 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行中被重新评估,因此匹配,因此再次设置了属性。我不明白。
我需要做什么才能使所有操作按预期执行?
答案 0 :(得分:2)
Where
是一个延迟执行查询。它不会立即求值并填充集合。相反,它会在本身迭代时执行-扫描原始源以查找匹配项。每次迭代时都会执行此操作。造成这种情况的原因包括可组合性和内存使用情况。实际上,不仅源数据可以在查询创建和迭代之间更改,而且由于“捕获的变量”的工作方式,过滤器本身也可以在这一次之间更改!
基本上:如果要立即将其执行到列表中,请在.ToList()
之后添加Where(...)
:
var zeroGroupings = ruleList.Rules.Where(r => r.DiagnosticGrouping == 0).ToList();