Qual è lo scopo della classe Expression?

c# expression-trees lambda

Domanda

Mi chiedo quale sia esattamente la differenza tra il wrapping di un delegato all'interno di Expression<> e non?

Vedo che Expression<Foo> viene utilizzato molto con LinQ, ma finora non ho trovato nessun articolo che spieghi la differenza tra questo e l'utilizzo di un delegato.

Per esempio

Func<int, bool> Is42 = (value) => value == 42;

vs.

Expression<Func<int, bool>> Is42 = (value) => value == 42;

Risposta accettata

Memorizzando un lambda come delegato, si memorizza un'istanza specifica di un delegato che esegue un'azione. Non può essere modificato, basta chiamarlo. Una volta che hai il tuo delegato, hai opzioni limitate nell'ispezionare cosa fa e cosa no.

Memorizzando una lambda come espressione, si memorizza un albero di espressioni che rappresenta il delegato. Può essere manipolato per fare altre cose come cambiarne i parametri, cambiare il corpo e farlo fare qualcosa di radicalmente diverso. Potrebbe anche essere compilato di nuovo a un delegato in modo da poterlo chiamare se lo si desidera. Puoi facilmente ispezionare l'espressione per vedere quali sono i suoi parametri, cosa fa e come lo fa. Questo è qualcosa che un provider di query può utilizzare per comprendere e tradurre un'espressione in un'altra lingua (come scrivere una query SQL per un albero di espressioni corrispondente).

È anche molto più facile creare un delegato utilizzando espressioni dinamicamente di quanto non stia emettendo il codice. Puoi pensare al tuo codice a un livello più alto come espressioni che è molto simile a come un compilatore visualizza il codice anziché andare a basso livello e visualizzare il tuo codice come istruzioni IL.

Quindi con un'espressione, sei in grado di fare molto più di un semplice delegato anonimo. Anche se non è veramente gratuito, le prestazioni avranno un impatto se si eseguono espressioni compilate rispetto a un metodo normale o un delegato anonimo. Ma questo potrebbe non essere un problema in quanto gli altri vantaggi nell'uso delle espressioni potrebbero essere importanti per te.


Risposta popolare

Func<> è solo un tipo delegato. Un'espressione è una rappresentazione runtime dell'albero completo delle operazioni che, facoltativamente, può essere compilata in fase di runtime in un delegato. È questo albero che viene analizzato dai parser di espressioni come Linq-to-SQL per generare istruzioni SQL o fare altre cose intelligenti. Quando assegni un lambda a un tipo di espressione, il compilatore genera questo albero di espressioni e anche il solito codice IL. Altro sugli alberi di espressione .



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché