代表如何记住它的参数?

时间:2013-12-11 11:25:58

标签: c# parameters delegates

考虑以下代码:

public ModelView(Model model) : this()
{
    Loaded += (object sender, RoutedEventArgs e) =>
    {
        DataContext = model;
    };
}

Loaded事件再次运行时,参数model会出现在内存中,但它从未明确保存过,是吗?

2 个答案:

答案 0 :(得分:4)

当您创建匿名方法或lambda时,编译器会在幕后创建一个新类,其中包含一些内部名称,如<ModelView>ctor_0或类似内容。这个类有一个方法,它是lambda的内容,但它也有 capture 属性,其中定义了lambda的本地函数状态,并使它可用于lambda。

请参阅MSDN上Lambda Expression文档中的 Lambda Expressions中的变量范围部分:

  

以下规则适用于lambda表达式中的变量范围:

     
      
  • 在引用它的委托变得有资格进行垃圾回收之前,捕获的变量不会被垃圾收集。   lambda表达式中引入的变量在外部方法中不可见。
  •   
  • lambda表达式无法直接从封闭方法中捕获ref或out参数。
  •   
  • lambda表达式中的return语句不会导致封闭方法返回。
  •   
  • 如果跳转语句的目标位于块之外,则lambda表达式不能包含lambda函数内的goto语句,break语句或continue语句。如果目标在块内,则在lambda函数块外部使用跳转语句也是错误的。
  •   

答案 1 :(得分:2)

除了@ Avner的回答,这就是C#编译器(有点)为你生成的内容:

public ModelView(Model model) : this()
{
    var closure = new AnonymousClass { _this = this, model = model };

    Loaded += closure.Loaded;
}

private class AnonymousClass
{
    public ModelView _this;
    public Model model;

    public void Loaded(object sender, RoutedEventArgs e)
    {
        _this.DataContext = model;
    }
}