Do.. While.. 使用 Exists 谓词。访问修改后的闭包?
Posted
技术标签:
【中文标题】Do.. While.. 使用 Exists 谓词。访问修改后的闭包?【英文标题】:Do.. While.. with Exists predicates. Access to modified closure? 【发布时间】:2011-06-13 16:10:32 【问题描述】:string reference;
do
reference = GenerateNewReference();
while (currentItems.Exists(i=>i.Reference.Equals(reference));
ReSharper 正在警告我这点,称为 Access to Modified Closure。我已尽力阅读并理解它,但我的代码对我来说仍然很好。
我的代码有问题吗?
【问题讨论】:
【参考方案1】:在您的情况下这很好,因为 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
。
【讨论】:
【参考方案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)));
【讨论】:
以上是关于Do.. While.. 使用 Exists 谓词。访问修改后的闭包?的主要内容,如果未能解决你的问题,请参考以下文章
各位懂软件,的分别使用while和do…whil循环输出1—10之间的所有数字,包括1和10这题咋做