Pergunta

Este não é claramente aparece como não seria uma boa prática. Alguém pode explicar por que não seria uma boa prática ou como isso funciona? Quaisquer livros ou artigos fornecendo uma explicação seria apreciada.

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

}

O valor que está de saída é o segundo valor "Modificado" . Que parte da magia do compilador está fazendo este trabalho? É este tão simples como manter o controle do valor na pilha e recuperá-lo novamente mais tarde?

[Edit]: Dado alguns dos comentários, alterando a sentença original alguns ...

Foi útil?

Solução

CurrentValue não é mais uma variável local: é uma variável capturado . Isso compila para algo como:

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

Jon Skeet tem realmente um bom escrever isso em C # in Depth , e um separado ( não como detalhado) discussão aqui .

Note que a variável CurrentValue agora está na pilha, não a pilha -. Isso tem muitas implicações, não menos importante, que agora podem ser usados ??por vários chamadores

Isso é diferente de java: em java o valor de uma variável é capturado. Em C #, o em si variável é capturada.

Outras dicas

Suponho mais a pergunta que eu estou pedindo é que como é trabalhar com uma variável local [MG edit: "Ack - ignorar este ..." foi adicionado posteriormente]

Este é o ponto; ele realmente não uma variável local mais - pelo menos, não em termos de como nós pensamos normalmente deles (na pilha etc). Parece que um, mas não é.

E para informações, re "não boas práticas" - métodos anônimos e variáveis ??capturadas são realmente uma ferramenta incrivelmente poderosa, especialmente quando se trabalha com eventos. Sinta-se livre para usá-los, mas se você está indo por este caminho, eu recomendaria pegar o livro de Jon para se certificar de que você entender o que está realmente acontecendo.

Você precisa capturar o valor da variável dentro do fechamento / delegado, então ele pode ser modificado, como você viu.

Atribuir CurrentValue a uma variável local (interior) para o delegado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top