这事儿常常发生
ReSharper 警告您,count
您分配为“验证完成”事件处理程序的 lambdas 隐式捕获了它,并且它的值很可能在创建 lambda 时(即,当您分配事件处理程序时)和它被调用。如果发生这种情况,lambda 将看不到人们直观期望的值。
一个例子:
int count = itemsToValidate.Count;
foreach(var item in itemsToValidate)
{
item.ValidateAsync += (x, y) => this.HandleValidate(ref count);
}
// afterwards, at some point before the handlers get invoked:
count = 0;
在这种情况下,处理程序将读取 count 的值0
而不是itemsToValidate.Count
-- 这可能被称为“显而易见的”,但对于许多不熟悉 lambdas 机制的开发人员来说,这是令人惊讶和违反直觉的。
我们通常是这样解决的
“关闭 R#”的通常解决方案是将捕获的变量移动到内部范围内,在该范围内它的可访问性要小得多,并且 R# 可以证明在评估 lambda 之前它不能被修改:
int count = itemsToValidate.Count;
foreach(var item in itemsToValidate)
{
int inner = count; // this makes inner impossible to modify
item.ValidateAsync += (x, y) => this.HandleValidate(ref inner);
}
// now this will of course not affect what the lambdas do
count = 0;
但你的情况很特殊
您的特殊情况是您特别想要这种行为的相对罕见的情况,并且使用上述技巧实际上会使程序行为不正确(您需要捕获的引用指向相同的计数)。
正确的解决方案:使用 R# 识别的特殊行注释禁用此警告。