与代表局部变量(Local variables with Delegates)

2019-07-19 20:57发布

显然不是看起来像它不会是一个最佳实践。 有人可以解释为什么它不会是一个最佳实践或如何工作的? 任何书籍或提供的说明文章,将不胜感激。

//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";

}

即输出的值是“修饰”的第二值。 哪一部分的编译器魔法使这项工作? 这是一样简单保持在堆上价值轨道,稍后再取回呢?

[编辑]:鉴于一些意见,改变原句的一些...

Answer 1:

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#的深度 ,和一个独立的(而不是详细)讨论在这里 。

注意变量CurrentValue的现在是在堆上,而不是堆栈 - 这有很多含义的,并非最不重要的,它现在可以通过不同的来电者使用。

这是对Java不同:在Java中的变量的被捕获。 在C#, 变量本身被捕获。



Answer 2:

我想更多的,我问的问题是,它是如何与一个局部变量工作[MG编辑:“确认 - 忽略此...”是后来加入的]

这就是重点; 它真的不是一个局部变量更多-至少,不是我们通常是如何认为他们(在堆栈等)方面。 它看起来像一个,但事实并非如此。

而对于信息,再“不良好做法” -匿名方法和捕获的变量实际上是一种非常强大的工具, 特别是处理事件时。 随意使用它们,但如果你走这条路,我会建议拿起乔恩的书,以确保您了解什么是真正发生的事情。



Answer 3:

您需要关闭/委托中捕捉变量的值,否则可以修改的,就像你看到的。

指定CurrentValue的一个局部变量(内部)的委托。



文章来源: Local variables with Delegates