Condividi tramite


Alberi delle espressioni

Gli alberi delle espressioni rappresentano il codice in una struttura di dati simile ad albero, in cui ogni nodo è un'espressione, ad esempio una chiamata al metodo o un'operazione binaria, ad x < yesempio .

Se si usa LINQ, si ha esperienza con una libreria avanzata in cui i Func tipi fanno parte del set di API. Se non si ha familiarità con LINQ, è probabile che si voglia leggere l'esercitazione su LINQ e l'articolo sulle espressioni lambda prima di questa. Gli alberi delle espressioni offrono un'interazione più completa con gli argomenti che sono funzioni.

Gli argomenti della funzione vengono scritti, in genere usando espressioni lambda, quando si creano query LINQ. In una tipica query LINQ questi argomenti di funzione vengono trasformati in un delegato creato dal compilatore.

Si scrive già codice che usa alberi delle espressioni. Le API LINQ di Entity Framework accettano alberi delle espressioni come argomenti per il modello di espressione di query LINQ. Ciò consente a Entity Framework di convertire la query scritta in C# in SQL eseguita nel motore di database. Un altro esempio è Moq, un framework di simulazione diffuso per .NET.

Quando si vuole avere un'interazione più completa, è necessario usare alberi delle espressioni. Gli alberi delle espressioni rappresentano il codice come struttura esaminata, modificata o eseguita. Questi strumenti consentono di modificare il codice durante l'esecuzione. Si scrive codice che esamina gli algoritmi in esecuzione o inserisce nuove funzionalità. Negli scenari più avanzati si modificano gli algoritmi in esecuzione e si convertono anche espressioni C# in un altro modulo per l'esecuzione in un altro ambiente.

Il codice viene compilato ed eseguito rappresentato dagli alberi delle espressioni. La compilazione e l'esecuzione di alberi delle espressioni consentono la modifica dinamica del codice eseguibile, l'esecuzione di query LINQ in vari database e la creazione di query dinamiche. Per altre informazioni sugli alberi delle espressioni in LINQ, vedere Come usare alberi delle espressioni per compilare query dinamiche.

Gli alberi delle espressioni vengono usati anche in DLR (Dynamic Language Runtime) per garantire l'interoperabilità tra linguaggi dinamici e .NET e consentire ai writer del compilatore di generare alberi delle espressioni anziché microsoft intermediate language (CIL). Per ulteriori informazioni su DLR, vedere Panoramica del Dynamic Language Runtime.

È possibile fare in modo che il compilatore C# o Visual Basic crei un albero delle espressioni automaticamente in base a un'espressione lambda anonima, oppure è possibile creare manualmente alberi delle espressioni usando lo spazio dei nomi System.Linq.Expressions.

Quando un'espressione lambda viene assegnata a una variabile di tipo Expression<TDelegate>, il compilatore genera codice per compilare un albero delle espressioni che rappresenta l'espressione lambda.

Gli esempi di codice seguenti illustrano come fare in modo che il compilatore C# crei un albero delle espressioni che rappresenta l'espressione num => num < 5lambda .

Expression<Func<int, bool>> lambda = num => num < 5;

Crei alberi di espressioni nel codice. Costruisci l'albero creando ogni nodo e collegando i nodi in una struttura ad albero. Si apprenderà come creare espressioni nell'articolo sulla creazione di alberi delle espressioni.

Gli alberi delle espressioni non sono modificabili. Se si desidera modificare un albero delle espressioni, è necessario costruire un nuovo albero delle espressioni copiando quello esistente e sostituendo i nodi in esso contenuti. Si usa un visitatore dell'albero delle espressioni per attraversare l'albero delle espressioni esistente. Per ulteriori informazioni, vedere l'articolo sulla traduzione di alberi di espressioni.

Dopo aver compilato un albero delle espressioni, si esegue il codice rappresentato dall'albero delle espressioni.

Limitazioni

Il compilatore C# genera alberi delle espressioni solo da espressioni lambda (o lambda a riga singola). Non può analizzare le lambda di espressione (o lambda su più righe). Per altre informazioni sulle espressioni lambda in C#, vedere Espressioni lambda.

Esistono alcuni elementi del linguaggio C# più recenti che non si traducono bene in alberi delle espressioni. Gli alberi delle espressioni non possono contenere await espressioni o async espressioni lambda. Molte delle funzionalità aggiunte in C# 6 e versioni successive non vengono visualizzate esattamente come scritte negli alberi delle espressioni. Al contrario, le funzionalità più recenti vengono esposte negli alberi delle espressioni nella sintassi equivalente, se possibile. Altri costrutti non sono disponibili. Significa che il codice che interpreta gli alberi delle espressioni funziona allo stesso modo quando vengono introdotte nuove funzionalità del linguaggio. Tuttavia, anche con queste limitazioni, gli alberi delle espressioni consentono di creare algoritmi dinamici che si basano sull'interpretazione e la modifica del codice rappresentato come struttura di dati. Consente a librerie avanzate, ad esempio Entity Framework, di eseguire le operazioni eseguite.

Gli alberi delle espressioni non supportano nuovi tipi di nodo di espressione. Si tratta di una modifica che causa un'interruzione per tutte le librerie che interpretano gli alberi delle espressioni per introdurre nuovi tipi di nodo. L'elenco seguente include la maggior parte degli elementi del linguaggio C# che non possono essere usati: