访问Lambda表达式中的Modified Closure

时间:2012-02-08 00:26:15

标签: c# linq lambda closures

foreach(var category in categories) {
    a.AddRange(_db.Articles.Where(c => c.Categories.Contains(category)));
}

代码运行正常但我在lambda表达式中使用的category引用了“访问修改后的闭包”的警告。

问题:在这种情况下是否有任何后果的警告?

2 个答案:

答案 0 :(得分:6)

此处的警告是因为您正在访问category lambda的闭包内的变量Where。值category随每次迭代而变化,Where延迟执行,因此它将看到category的当前值与lambda创建时的值。

在这种情况下,你很可能。即使Where进行延迟评估,AddRange方法也会提示,并会强制评估Where完成。因此Where方法会看到它所期望的category的值。

如果您想要删除警告,只需声明迭代变量的本地副本并将其捕获。

foreach(var category in categories) {
  var localCategory = category;
  a.AddRange(_db.Articles.Where(c => c.Categories.Contains(localCategory)));
}

答案 1 :(得分:0)

它告诉您“category”变量存在于闭包中,可以在LINQ表达式之外进行修改。

查看问题here以获得一些解释。