在我的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; ");
答案 0 :(得分: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();
}
这将打印数字5
5次,因为表达式捕获i
,而不是i
的值。由于i
的值在循环的每次迭代中都会发生变化,因此每次操作将打印的值每次i
都会更改,最终会降落到5
,因为它是边界条件为了循环。
至于你给出的具体例子,因为Where
被懒惰地评估(同样,它永远不会是null,它只是一个可枚举的第一次尝试无法移动到下一条记录),如果您通过在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; ");
使您的支票有效