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)?
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();
}