代码之家  ›  专栏  ›  技术社区  ›  hugoware

带有委托的局部变量

  •  22
  • hugoware  · 技术社区  · 17 年前

    显然不是

    //The constructor
    public Page_Index() {
    
        //create a local value
        string currentValue = "This is the FIRST value";
    
        //use the local variable in a delegate that fires later
        this.Load += delegate(object sender, EventArgs e) {
            Response.Write(currentValue);
        };
    
        //change it again
        currentValue = "This is the MODIFIED value";
    
    }
    

    输出的值是第二个值 . 编译器魔力的哪一部分使它起作用?这和跟踪堆上的值并稍后再次检索它一样简单吗?

    [编辑]:给出一些评论,将原来的句子修改一些。。。

    3 回复  |  直到 5 年前
        1
  •  30
  •   Marc Gravell    15 年前

    currentValue不再是局部变量:它是一个 捕获 变量这可编译为以下内容:

    class Foo {
      public string currentValue; // yes, it is a field
    
      public void SomeMethod(object sender, EventArgs e) {
        Response.Write(currentValue);
      }
    }
    ...
    public Page_Index() {
      Foo foo = new Foo();
      foo.currentValue = "This is the FIRST value";
      this.Load += foo.SomeMethod;
    
      foo.currentValue = "This is the MODIFIED value";
    }
    

    C# in Depth ,以及单独(不太详细)的讨论 here .

    这与java不同:在java中 价值 捕获变量的类型。在C#中 变量本身 他被捕了。

        2
  •  2
  •   Marc Gravell    17 年前

    这就是重点;真的吗 一个局部变量——至少,不是我们通常认为的(堆栈上的)局部变量。看起来像,但不是。

    关于信息,我们称之为“不好的做法”——匿名方法和捕获的变量实际上是一个非常强大的工具, 尤其地 在处理事件时。可以随意使用它们,但如果你走这条路,我建议你拿起乔恩的书,以确保你了解实际发生的事情。

        3
  •  0
  •   leppie    17 年前

    您需要捕获闭包/委托中变量的值,否则可以修改它,如您所见。