Aggiornamento: Questo non è più un problema da C# 6, che ha introdotto l'operatore nameof
per affrontare tali scenari (vedi MSDN).
Sembra che la risposta alla mia domanda è non; la funzione non è standardizzata. La situazione sembra ancora più cupa di quanto avessi inizialmente sospettato; non solo la promozione delle variabili catturate non è standardizzata, ma lo è anche l'intera specifica della conversione di funzioni anonime alle loro rappresentazioni di alberi di espressione.
L'implicazione di questo è che le funzioni anonime anche semplici, come il basso, non si garantisce che producono strutture di espressione coerenti tra diverse implementazioni del quadro (fino a quando la conversione è standardizzata):
Expression<Func<int, int, int>> add = (int x, int y) => x + y;
I seguenti estratti sono presi dallo C# Language Specification 4.0 (enfasi aggiunta in tutti i casi).
Da “tipi di alberi 4.6 di espressione”:
La definizione esatta del tipo generico Expression<D>
nonché le regole precise per la costruzione di un albero di espressione quando una funzione anonima viene convertito in un tipo di albero di espressione, sono entrambi al di fuori dello scopo di questa specifica e sono descritti altrove.
Da “6.5.2 Valutazione delle conversioni funzioni anonime a tipi di alberi espressione”:
Conversione di una funzione anonima in un tipo albero di espressione produce un albero di espressione (§4.6). Più precisamente, la valutazione della conversione della funzione anonima porta alla costruzione di una struttura oggetto che rappresenta la struttura della funzione anonima stessa. La struttura precisa dell'albero delle espressioni e il processo esatto per crearlo sono definiti dall'implementazione.
Il terzo esempio in “6.5.3 esempio attuazione” dimostra la conversione di una funzione anonima che cattura una variabile locale, e conferma la promozione variabile citato nella mia interrogazione:
La durata di la variabile locale deve ora essere estesa almeno alla durata del delegato della funzione anonima. Questo può essere ottenuto "issando" la variabile locale in un campo di una classe generata dal compilatore. L'istanziazione della variabile locale (§7.15.5.2) corrisponde quindi alla creazione di un'istanza della classe generata dal compilatore e l'accesso alla variabile locale corrisponde all'accesso a un campo nell'istanza della classe generata dal compilatore.
Questo è ulteriormente confermata alla fine della sezione:
La stessa tecnica applicata qui per catturare variabili locali può essere utilizzato anche per la conversione funzioni anonime per alberi di espressione: I riferimenti agli oggetti compilatore generato può essere memorizzato nell'albero delle espressioni e l'accesso alle variabili locali è possibile rappresentarlo come accesso al campo su questi oggetti, . Il vantaggio di questo approccio è che consente di condividere le variabili locali "sollevate" tra i delegati e gli alberi di espressione.
Tuttavia, c'è un disclaimer all'inizio della sezione:
La realizzazione qui descritto si basa sugli stessi principi utilizzati dal Microsoft compilatore C#, ma è in alcun modo un implementazione obbligatoria, né è l'unica possibile. Si parla solo brevemente di conversioni in alberi di espressione, poiché la loro esatta semantica non rientra nell'ambito di questa specifica.
P.S. Eric Lippert confirms in this comment che le specifiche dell'albero dell'espressione non sono mai state spedite. Esiste un Expression Trees v2 Spec nella documentazione DLR su CodePlex, ma il suo ambito non sembra coprire la conversione di funzioni anonime in alberi di espressioni in C#.
È possibile rilevare le alternative qui: http://stackoverflow.com/questions/72121/finding-the-variable-name-passed-to-a-function-in-c-sharp ma di nuovo non documentato. L'approccio di tipo anonimo è molto più veloce anche se .. – nawfal