【问题标题】:Does `this.SomeMethod` passed as Func argument capture `this`?作为 Func 参数传递的 `this.SomeMethod` 是否捕获 `this`?
【发布时间】:2019-03-12 13:20:56
【问题描述】:

如果一个方法要求一些Func:

void Foo(Func<string> stringFactory);

然后传递一个引用 this 的 lambda 引入变量捕获:

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

在传递实例方法而不是 lambda 时也会发生这种情况吗?

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

string GetMagicString()
{
    return "Bar";
}

如果是这样,这是否编译为与 lambda 版本类似的东西?

如果没有,它如何同时传递方法(存在于某处)和实例(存在于其他地方)?

【问题讨论】:

    标签: c# lambda delegates capture func


    【解决方案1】:

    this 不必在此处的闭包中捕获。调用之间的区别在于() =&gt; this.MagicStringProperty() 有一个编译器生成的方法。这个方法简单的调用this.GetMagicString()

    如果您反编译代码,您将看到Foo(this.GetMagicString) 转换为this.Foo(new Func&lt;string&gt;((object) this, __methodptr(GetMagicString)))Foo(() =&gt; this.GetMagicString()) 转换为this.Foo(new Func&lt;string&gt;((object) this, __methodptr(&lt;.ctor&gt;b__1_0))),其中&lt;.ctor&gt;b__1_0 是编译器生成的调用this.GetMagicString() 的方法:

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

    【讨论】:

    • 所以如果我理解正确的话,会构造一个Func 来保存对this 的引用和对方法的引用?这是否也意味着每次调用都会执行一次分配,new Func&lt;string&gt;(...)
    • @Timo:是的,是的。
    • 谢谢。这实际上相当令人失望。我想知道他们是否不能用结构轻松地做到这一点......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多