ReSharper/Linq 错误:访问修改后的闭包
本文关键字:修改 闭包 访问 Linq 错误 ReSharper | 更新日期: 2023-09-27 18:17:57
在我的 ASP MVC 3 站点上的验证.cs
文件中,我正在尝试对数据库运行快速检查是否存在用户输入的代理 ID 号。但是,ReSharper 正在识别读取 Access to modified closure
的 agentId
变量下的错误。我不确定这个错误是什么意思,或者这个陈述有什么问题。
这是我们写入验证程序的帮助程序方法。它不是在循环上设置的,而是在五个位置之一检测到代理 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; ");
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,它只是一个在第一次尝试时无法移动到下一条记录的枚举(,如果你要在 if
语句后再次枚举它来评估check
,迭代时的当前 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; ");
使您的支票有效