为什么要使用局部变量?

4

Resharper建议我将此变量作为本地变量,并写下"access to modified closure"。

if (filter != null)
{
    if (filter.CityId != 0)
    {
        ads = ads.Where(x => x.Ad.CityId == filter.CityId);
    }
    if (filter.BusinesCategoryId != 0)
    {
        ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId);
    }
}

为什么要对局部变量进行过滤?

2
哪个本地变量,ads - Tigran
2个回答

6
由于您的查询(Where(...))没有被执行,我假设筛选条件是从循环中获取的?Linq查询只有在使用时才会被执行。因此,如果您循环遍历了一堆筛选条件,然后稍后开始执行它们,那么查询中的筛选条件值将是错误的。
类似的问题:Access to Modified Closure,还有:http://devnet.jetbrains.net/thread/273042。需要查看更多代码才能确定100%肯定。

有循环时是危险的吗?我不进行循环。 - Mediator
2
闭包可以在没有循环的情况下进行修改。循环是不经意间修改闭包变量的最常见原因,但它并不是唯一的原因。 - phoog

3
据我理解,如果您从委托(闭包)中访问变量,然后在执行委托之前修改变量,Resharper将会抛出错误。这通常发生在您在循环内部访问for循环变量并在循环外部执行时。如果您的代码如下所示:
foreach (filter in filters)
{
      if (filter != null)  {
            if (filter.CityId != 0)      {
                ads = ads.Where(x => x.Ad.CityId == filter.CityId);
            }
            if (filter.BusinesCategoryId != 0)      {
                ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId);
            }
      }
} 
return ads.ToList()

然后它的行为就不会像你期望的那样。但是,如果在循环范围内执行lambda表达式,则不会有任何问题。 我不会解释为什么会出现这种行为,因为很多人已经解释得非常好: - Eric Lippert's Blog - ReSharper Warning - Access to Modified Closure - Is there a reason for C#'s reuse of the variable in a foreach? 更新:回答“为什么使用局部变量?”是因为解决上述问题的方法是使用一个局部变量(即在循环内部),并在lambda中使用该变量。这样,您就可以针对每个lambda实例关闭变量的不同实例。

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