1

在我的 ASP MVC 3 站点上的验证.cs文件中,我正在尝试对数据库进行快速检查,以确定是否存在用户输入的代理 ID 号。但是,ReSharper 在agentId读取Access to modified closure. 我不确定这个错误是什么意思,或者这个陈述有什么问题。

这是我们写入验证程序的辅助方法。它不是在循环上设置的,而是在五个位置之一检测到代理 ID 时从上方调用。

这是调用的代码StatValidation

if (String.IsNullOrEmpty(agt.AgencyId1))
{
   _sb.Append("One Agency Id is required; ");
}
else
{
    StatValidation(agt.AgencyCompany1, 
              agt.AgencyId1.Trim(), agt.AgencyIdType1, 1);
}

//Conditionally validate remaining Agent IDs
if (!String.IsNullOrWhiteSpace(agt.AgencyId2) || 
    !String.IsNullOrWhiteSpace(agt.AgencyCompany2))
{
    StatValidation(agt.AgencyCompany2, agt.AgencyId2, agt.AgencyIdType1, 2);
}

这是给出错误的方法标题和代码行

private static void StatValidation(string company, 
      string agentId, string idType, int i)
{
   AgentResources db = new AgentResources();
   // ReSharper is highlighting 'agentId' with the error 
   // 'Access to modified closure'
   var check = db.SNumberToAgentId.Where(x => x.AgentId.Equals(agentId));

   if (check == null) _sb.Append("Agent ID not found; ");
4

1 回答 1

12

Access to modified closure消息意味着您的表达式正在捕获一个变量,该变量在捕获后确实/可能会更改其值。考虑以下

var myList = new List<Action>();

for(var i = 0; i < 5; ++i)
{
    myList.Add(() => Console.WriteLine(i));
}

foreach(var action in myList)
{
    action();
}

这将打印数字55 次,因为i它是由表达式捕获的,而不是 的值i。由于i循环的每次迭代中的值都会发生变化,因此每次操作将打印的值都会发生变化i,最终会着陆,5因为它是循环的边界条件。

至于你给出的具体例子,因为Where是懒惰地评估的(而且,它永远不会为空,它只是一个在第一次尝试时无法移动到下一条记录的可枚举),如果你要评估check的话在您的if语句之后再次枚举它,迭代时的当前agentId将被评估,不一定是参数的原始值。

要解决此问题,请更改:

var check = db.SNumberToAgentId.Where(x => x.AgentId.Equals(agentId));

对此:

var check = db.SNumberToAgentId.Where(x => x.AgentId.Equals(agentId)).ToList();

这会强制Where迭代器仅被评估一次,当前agentId位于该行,如果agentId稍后在方法中发生更改,则该更改不会影响 的值check

另外,改变:

if (check == null) _sb.Append("Agent ID not found; ");

对此:

if (check.Count == 0) _sb.Append("Agent ID not found; ");

使您的支票有效

于 2013-06-10T17:59:05.960 回答