Why does ReSharper tell me “implicitly captured closure”?

前端 未结 5 1837
我在风中等你
我在风中等你 2020-12-04 06:20

I have the following code:

public double CalculateDailyProjectPullForceMax(DateTime date, string start = null, string end = null)
{
    Log(\"Calculating Dai         


        
5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-04 06:48

    Agreed with Peter Mortensen.

    The C# compiler generates only one type that encapsulates all variables for all lambda expressions in a method.

    For example, given the source code:

    public class ValueStore
    {
        public Object GetValue()
        {
            return 1;
        }
    
        public void SetValue(Object obj)
        {
        }
    }
    
    public class ImplicitCaptureClosure
    {
        public void Captured()
        {
            var x = new object();
    
            ValueStore store = new ValueStore();
            Action action = () => store.SetValue(x);
            Func f = () => store.GetValue();    //Implicitly capture closure: x
        }
    }
    
    
    

    The compiler generates a type looks like :

    [CompilerGenerated]
    private sealed class c__DisplayClass2
    {
      public object x;
      public ValueStore store;
    
      public c__DisplayClass2()
      {
        base.ctor();
      }
    
      //Represents the first lambda expression: () => store.SetValue(x)
      public void Capturedb__0()
      {
        this.store.SetValue(this.x);
      }
    
      //Represents the second lambda expression: () => store.GetValue()
      public object Capturedb__1()
      {
        return this.store.GetValue();
      }
    }
    

    And the Capture method is compiled as:

    public void Captured()
    {
      ImplicitCaptureClosure.c__DisplayClass2 cDisplayClass2 = new ImplicitCaptureClosure.c__DisplayClass2();
      cDisplayClass2.x = new object();
      cDisplayClass2.store = new ValueStore();
      Action action = new Action((object) cDisplayClass2, __methodptr(Capturedb__0));
      Func func = new Func((object) cDisplayClass2, __methodptr(Capturedb__1));
    }
    
    
    

    Though the second lambda does not use x, it cannot be garbage collected as x is compiled as a property of the generated class used in the lambda.

    提交回复
    热议问题