【问题标题】:How does a delegate remember it's parameters? [duplicate]委托如何记住它的参数? [复制]
【发布时间】:2013-12-11 11:25:57
【问题描述】:

考虑这段代码:

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

Loaded 事件再次运行时,参数model 存在于内存中,但它从未显式保存,是吗?

【问题讨论】:

  • 也许this 会有所帮助。
  • 被保存,但是编译器在幕后做了。
  • 好的,谢谢,一切都清楚了,它在幕后部分 - 将删除问题。
  • 你可以一直读到奶牛回家,当你真正看到它时仍然会感到惊讶。

标签: c# parameters delegates


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多