Search code examples
c#lambdadelegatescapturefunc

Does `this.SomeMethod` passed as Func argument capture `this`?


If a method asks for some Func:

void Foo(Func<string> stringFactory);

Then passing a lambda referencing this introduces variable capturing:

Foo(() => this.MagicStringProperty); // Captures `this`

Does this happen also when passing an instance method instead of a lambda?

Foo(this.GetMagicString); // Capturing??

string GetMagicString()
{
    return "Bar";
}

If so, is this compiled to a similar thing as the lambda version?

If not, how does it manage to pass both the method (which exists somewhere) and the instance (which exists somewhere else)?


Solution

  • this doesn't have to be captured in a closure here. The difference between the calls is that there is a compiler generated method for () => this.MagicStringProperty(). This method simply calls this.GetMagicString().

    If you decompile the code you will see that Foo(this.GetMagicString) translates to this.Foo(new Func<string>((object) this, __methodptr(GetMagicString))) and that Foo(() => this.GetMagicString()) translates to this.Foo(new Func<string>((object) this, __methodptr(<.ctor>b__1_0))) where <.ctor>b__1_0 is the compiler generated method that calls this.GetMagicString():

    [CompilerGenerated]
    private string <.ctor>b__1_0()
    {
      return this.GetMagicString();
    }