string reference;
do {
reference = GenerateNewReference();
} while (currentItems.Exists(i=>i.Reference.Equals(reference));
ReSharper警告我有关此事的信息,称为Access to Modified Closure。我尽我所能来阅读和理解它,但我的代码对我来说似乎仍然很好。做..虽然..与存在的谓词。访问修改后的关闭?
我的代码有问题吗?
string reference;
do {
reference = GenerateNewReference();
} while (currentItems.Exists(i=>i.Reference.Equals(reference));
ReSharper警告我有关此事的信息,称为Access to Modified Closure。我尽我所能来阅读和理解它,但我的代码对我来说似乎仍然很好。做..虽然..与存在的谓词。访问修改后的关闭?
我的代码有问题吗?
不,没有问题,因为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)));
你的情况很好,因为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
拉姆达通过引用结合myInt
,而不是价值。