我知道在SO上有很多关于这个问题的话题,Eric Lippert还有一篇很棒的帖子。我仍然不太确定以下代码中发生了什么以及Resharper警告的原因:
public class Class
{
public string Id { get; set; }
}
public class GenericClass<T>
{
public virtual bool Exists(Predicate<T> match)
{
return true;
}
}
public class Main
{
public void Test()
{
var list = new List<Class>();
var list2 = new GenericClass<Class>();
foreach (var item in list)
{
if (list2.Exists(o => o.Id == item.Id)) // access to variable in closure on item
}
}
}
这可以通过以下方式轻松解决:
var localCopy = item;
if (list2.Exists(o => o.Id == localCopy.Id))
据我所知,所有在exists中创建的闭包确实引用了同一个实例,如果是localCopy,对吗?但这不应该是一个问题,因为存在是立即评估的吗?那我在哪里错了?
答案 0 :(得分:4)
但这不应该是一个问题,因为存在会立即评估吗?
是的,GenericClass.Exists
急切地评估lambda,但ReSharper并不知道。
所有ReSharper都知道你将一个闭包传递给另一个方法 - 该方法可能懒惰地执行lambda,因此警告。
有没有办法告诉resharper,对于那种方法,不需要警告?
查看文档,似乎可以使用InstantHandleAttribute
属性修饰谓词参数。
告诉代码分析引擎,如果在调用的方法处于堆栈时完全处理参数。如果参数是委托,则表示在执行方法时执行委托。如果参数是可枚举的,则表示在执行方法时枚举它
请参阅此处了解如何安装JetBrains代码注释属性:Annotations in Source Code