string reference;
do {
reference = GenerateNewReference();
} while (currentItems.Exists(i=>i.Reference.Equals(reference));
ReSharper正在警告我这件事,称为Access to Modified Closure。我已尽力阅读并理解它,但我的代码对我来说似乎还不错。
我的代码有问题吗?
答案 0 :(得分:4)
在你的情况下很好,因为reference
的值在你的lambda的生命周期内不会改变。但是,resharper并不知道。至于resharper可以看到lambda可能存活更长时间reference
改变其值。
该规则旨在在您编写如下代码时发出警告:
int myInt=1;
Func<int,bool> IsOne = i=>i==myInt;
myInt=2;
IsOne(1);//=> false
IsOne(2);//=> true
因为IsOne
lambda通过引用绑定到myInt
,而不是通过值绑定。
答案 1 :(得分:2)
不,没有问题,因为List<T>.Exists
方法急切地执行。因此,捕获变量的值的变化立即“响应”。你做有一个修改后的闭包,但这不一定(在这种情况下)是错误的。
另一方面,如果您将“lambda”(实际上是委托)添加到循环内的列表中,然后再运行这些查询,那么您将遇到Resharper所遇到的实际修改后的闭包问题。警告你。
如果想要摆脱警告,你可以这样做:
string reference;
do {
reference = GenerateNewReference();
var refCopy = reference;
} while (currentItems.Exists(i => i.Reference.Equals(refCopy));
稍微偏离主题:如果您想要编写搜索方式(没有任何修改后的关闭警告),您可以编写一个实用程序方法,例如:
public static IEnumerable<T> Generate(Func<T> func)
{
if(func == null)
throw new ArgumentNullException("func");
while(true)
yield return func();
}
然后将其用作:
var result = MyExtensions.Generate(GenerateNewReference)
.First(reference => !currentItems.Exists(i => i.Reference.Equals(reference)));