Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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 < y
esempio .
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 < 5
lambda .
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:
- Metodi condizionali rimossi dall'output
-
base
accesso - Espressioni del gruppo di metodi, inclusi address-of (
&
) un gruppo di metodi ed espressioni di metodo anonime - Riferimenti alle funzioni locali
- Istruzioni, tra cui l'assegnazione (
=
) e le espressioni con corpo di istruzione - Metodi parziali con solo una dichiarazione di definizione
- Operazioni di puntatore non sicure
-
dynamic
Operazioni -
Operatori di unione con
null
il lato sinistro odefault
letterale, l'assegnazione di unione null e l'operatore di propagazione Null (?.
) - Inizializzatori di matrice multidimensionali, proprietà indicizzate e inizializzatori di dizionario
- espressioni di raccolta
-
throw
Espressioni - Accesso ai membri dell'interfaccia
static virtual
oabstract
- Espressioni lambda con attributi
- Stringhe interpolate
- Conversioni di stringhe UTF-8 o letterali di stringa UTF-8
- Chiamate al metodo tramite argomenti variabili, argomenti denominati o argomenti facoltativi
- Espressioni che usano System.Index o System.Range, operatore "from end" (
^
) o espressioni di intervallo (..
) -
async
espressioni lambda oawait
espressioni, inclusiawait foreach
eawait using
-
Tupla letterali, conversioni di tupla, tupla
==
o!=
, owith
espressioni -
Ignora (
_
), decostruzione dell'assegnazione, l'operatore di pattern matchingis
o l'espressione di pattern matchingswitch
- Chiamata COM con
ref
omessa negli argomenti -
ref
,in
oout
parametri,ref
valori restituiti,out
argomenti o valori diref struct
tipo