简体   繁体   English

在闭包中访问变量

[英]Access to variable in closure

I know there has been a lot topics about that issue on SO and there is also a great post from Eric Lippert . 我知道关于SO的问题很多,而且Eric Lippert也发表了一篇很棒的文章。 Still I'm not quite sure what is happening in the following code and the reason for the Resharper warning: 仍然我不太确定以下代码中发生了什么以及发出“ Reshaper”警告的原因:

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
    }
  }
}

This can be easily fixed by this: 这可以通过以下方式轻松解决:

var localCopy = item;
if (list2.Exists(o => o.Id == localCopy.Id))

As far as I understand all closures which are created in the exists does reference the same instance if localCopy, correct? 据我了解,如果localCopy正确,在存在的所有闭包中是否引用相同的实例? But this should not be an issue since the exists is evaluated instantly right? 但这不应该成为问题,因为对存在进行了立即评估,对吗? So where am I wrong here? 那我在哪里错了?

But this should not be an issue since the exists is evaluated instantly right? 但这不应该成为问题,因为对存在进行了立即评估,对吗?

Yes, GenericClass.Exists evaluates the lambda eagerly, but ReSharper doesn't know that. 是的, GenericClass.Exists急切地评估lambda,但是ReSharper并不知道这一点。

All ReSharper knows is that you're passing a closure to another method - that method might execute the lambda lazily, hence the warning. ReSharper所知道的就是,您正在将闭包传递给另一个方法-该方法可能会延迟执行lambda,因此出现警告。


Is there any way to tell resharper that, for that method, there is no need for the warning? 是否有任何方法可以告诉Resharper,对于该方法,不需要警告?

Looking at the documentation, it seems you could decorate the predicate parameter with the InstantHandleAttribute attribute. 查看文档, 看来您可以使用InstantHandleAttribute属性装饰谓词参数。

Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. 告诉代码分析引擎,当调用的方法在堆栈上时,参数是否已完全处理。 If the parameter is a delegate, indicates that delegate is executed while the method is executed. 如果参数是委托,则表示在执行方法的同时执行委托。 If the parameter is an enumerable, indicates that it is enumerated while the method is executed 如果参数是可枚举的,则表示在执行方法时将其枚举

See here for how to install JetBrains code annotation attributes: Annotations in Source Code 请参阅此处以了解如何安装JetBrains代码注释属性: 源代码中的注释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM