这显然不是看起来像它不会是一个最佳实践。 有人可以解释为什么它不会是一个最佳实践或如何工作的? 任何书籍或提供的说明文章,将不胜感激。
//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";
}
即输出的值是“修饰”的第二值。 哪一部分的编译器魔法使这项工作? 这是一样简单保持在堆上价值轨道,稍后再取回呢?
[编辑]:鉴于一些意见,改变原句的一些...
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#, 变量本身被捕获。
我想更多的,我问的问题是,它是如何与一个局部变量工作[MG编辑:“确认 - 忽略此...”是后来加入的]
这就是重点; 它真的不是一个局部变量更多-至少,不是我们通常是如何认为他们(在堆栈等)方面。 它看起来像一个,但事实并非如此。
而对于信息,再“不良好做法” -匿名方法和捕获的变量实际上是一种非常强大的工具, 特别是处理事件时。 随意使用它们,但如果你走这条路,我会建议拿起乔恩的书,以确保您了解什么是真正发生的事情。
您需要关闭/委托中捕捉变量的值,否则可以修改的,就像你看到的。
指定CurrentValue的一个局部变量(内部)的委托。