Alberi delle espressioni

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

Se si è usato LINQ, si ha esperienza con una ricca libreria in cui i tipi Func fanno parte del set di API. (Se non si ha familiarità con LINQ, è consigliabile leggere l'esercitazione su LINQ e l'articolo sulle espressioni lambda prima di questo). Gli alberi delle espressione offrono una migliore interazione con gli argomenti che sono funzioni.

Scrivere gli argomenti della funzione, in genere usando le espressioni lambda, quando si creano query LINQ. In una tipica query LINQ, tali argomenti delle funzioni vengono trasformati in un delegato che viene creato dal compilatore.

È probabile che si sia già scritto codice che usa gli alberi delle espressioni. Le API LINQ di Entity Framework accettano alberi delle espressioni come argomenti per il criterio di espressione di query LINQ. Ciò consente a Entity Framework di convertire la query scritta in C# in SQL che viene eseguito nel motore di database. Un altro esempio è Moq, che è un framework di simulazione tra i più diffusi per .NET.

Quando si vuole usare una maggiore interazione, è necessario usare gli alberi delle espressioni. Gli alberi delle espressioni rappresentano il codice come una struttura da esaminare, modificare o eseguire. Questi strumenti offrono la possibilità di modificare il codice in fase di esecuzione. È possibile scrivere codice che esamina gli algoritmi in esecuzione o inietta nuove funzionalità. Negli scenari più avanzati, è possibile modificare gli algoritmi in esecuzione e persino convertire le espressioni C# in un'altra forma per l'esecuzione in un altro ambiente.

È possibile compilare ed eseguire codice rappresentato dagli alberi delle espressioni. La compilazione e l'esecuzione di alberi delle espressioni consente 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 la compilazione di 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 dei compilatori di generare alberi delle espressioni anziché MSIL (Microsoft Intermediate Language). Per altre informazioni su DLR, vedere Dynamic Language Runtime Overview (Panoramica su Dynamic Language Runtime).

È possibile creare un albero delle espressioni tramite il compilatore di C# o di Visual Basic in base a un'espressione lambda anonima o creare tali alberi di espressioni manualmente tramite il nome spazio 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.

Il compilatore C# genera alberi delle espressioni solo da espressioni lambda (o lambda a riga singola). Non è in grado di analizzare le espressioni lambda dell’istruzione (o le espressioni lambda a più righe). Per altre informazioni sulle espressioni lambda in C#, vedere Espressioni lambda.

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

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

Creare alberi delle espressioni nel codice. Per compilare l'albero, creare ogni nodo e collegare i nodi in una struttura ad albero. Per apprendere a creare le espressioni, vedere l'articolo sulla creazione di alberi delle espressioni.

Gli alberi delle espressioni non sono modificabili. Per modificare un albero delle espressioni, è necessario crearne uno nuovo copiando quello esistente e sostituendone i nodi. È possibile usare un visitatore dell'albero delle espressioni per attraversare l'albero delle espressioni esistente. Per altre informazioni, vedere l'articolo sulla conversione degli alberi delle espressioni.

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

Limiti

Esistono alcuni elementi del linguaggio C# più recenti per cui la traslazione in alberi delle espressioni non funziona bene. Gli alberi delle espressioni non possono contenere espressioni await o espressioni lambda async. 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, quando è possibile. Non sono disponibili altri costrutti. Significa che il codice che interpreta gli alberi delle espressioni funziona allo stesso modo anche quando vengono introdotte nuove funzionalità del linguaggio. Tuttavia, nonostante queste limitazioni, gli alberi delle espressioni consentono di creare algoritmi dinamici che si basano sull'interpretazione e la modifica del codice rappresentato come struttura dei dati. Consente alle librerie avanzate come Entity Framework di svolgere la loro funzione.

Gli alberi delle espressioni non supportano nuovi tipi di nodi 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: