Questa domanda era the subject of my blog on the 20th of May 2013. Grazie per la bella domanda!
Stai fraintendendo cosa significhi "lessical scoped". Citiamo il documento che hai collegato a:
il corpo di una funzione viene valutato nel vecchio ambiente dinamico esistente al momento della definizione della funzione, non nell'ambiente corrente quando viene chiamata la funzione.
Ecco il codice:
int x = 1;
Func<int,int> f = y => x + y;
x = 2;
Console.WriteLine(f(1));
Ora, ciò che è "l'ambiente dinamico che esiste al momento è stata definita la funzione"? Pensa a un "ambiente" come a una classe. Quella classe contiene un campo mutabile per ogni variabile. Quindi questa è la stessa:
Environment e = new Environment();
e.x = 1;
Func<int,int> f = y => e.x + y;
e.x = 2;
Console.WriteLine(f(1));
Quando f
viene valutata, x
viene cercato nell'ambiente e che esisteva quando f è stato creato. Il contenuto di tale ambiente è stato modificato, ma l'ambiente che è f
associato a è lo stesso ambiente. (Si noti che questo è in realtà il codice che il compilatore C# genera! Quando si utilizza una variabile locale in un lambda, il compilatore genera una speciale classe "ambiente" e trasforma ogni utilizzo del locale in un utilizzo di un campo.)
Lasciatemi fare un esempio di come sarebbe il mondo se C# fosse stato applicato dinamicamente.Si consideri il seguente:
class P
{
static void M()
{
int x = 1;
Func<int, int> f = y => x + y;
x = 2;
N(f);
}
static void N(Func<int, int> g)
{
int x = 3;
Console.WriteLine(g(100));
}
}
Se C# è stata ambito dinamico allora questo sarebbe stampare "103", perché la valutazione g
valuta f
, e in una lingua ambito in modo dinamico, valutando f
sarebbe cercare il valore di x
nel contesto attuale. Nell'ambiente corrente è 3. Nell'ambiente esistente quando è stato creato f
, x
è 2. Ancora, il valore di x
in quell'ambiente è stato modificato; come indicato dal documento, l'ambiente è un ambiente dinamico. Ma quale ambiente è rilevante non cambia.
La maggior parte delle lingue in questi giorni non ha un ambito dinamico, ma ce ne sono alcune. PostScript, ad esempio, il linguaggio che viene eseguito sulle stampanti, viene applicato in modo dinamico.
Hai cambiato il valore di 'x' prima di richiamare' f'. Perché non ti aspetti di usare il valore attuale di 'x'? –
Perché 4? forse hai pensato 2? –
E perché 4? Vedo come potresti pensare f (1) = 2 ma dove avresti 4? – jure