Esporta (0) Stampa
Espandi tutto
Il presente articolo è stato tradotto automaticamente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale. Ulteriori informazioni.
Traduzione
Originale

Strutture ad albero dell'espressione (C# e Visual Basic)

Le strutture ad albero dell'espressione rappresentano il codice in una struttura di dati ad albero, in cui ogni nodo è un'espressione, ad esempio una chiamata al metodo o un'operazione binaria quale x < y.

È possibile compilare ed eseguire il codice rappresentato dalle strutture ad albero dell'espressione. In questo modo, è possibile modificare in modo dinamico il codice eseguibile, eseguire query LINQ in vari database e creare query dinamiche. Per ulteriori informazioni sulle strutture ad albero dell'espressione in LINQ, vedere Procedura: utilizzare strutture ad albero dell'espressione per la compilazione di query dinamiche (C# e Visual Basic) e Procedura dettagliata: creazione di un provider LINQ IQueryable.

Le strutture ad albero dell'espressione vengono utilizzate anche in DLR per offrire l'interoperabilità tra linguaggi dinamici e .NET Framework e consentire la generazione di tali strutture da parte dei writer di compilatori anziché di Microsoft Intermediate Language (MSIL). Per ulteriori informazioni su DLR, vedere Cenni preliminari su Dynamic Language Runtime.

È possibile creare una struttura ad albero dell'espressione automaticamente mediante il compilatore C# o Visual Basic in base a un'espressione lambda anonima o creare tali strutture manualmente tramite 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 una struttura ad albero dell'espressione che rappresenta l'espressione lambda.

I compilatori C# e Visual Basic possono generare strutture ad albero dell'espressione solo da espressioni lambda (o lambda a riga singola). Non è possibile analizzare lambda di istruzioni (o lambda a più righe). Per ulteriori informazioni sulle espressioni lambda in C#, vedere Espressioni lambda (Guida per programmatori C#); per Visual Basic, vedere Espressioni lambda (Visual Basic).

Negli esempi di codice seguenti viene illustrato come creare una struttura ad albero dell'espressione che rappresenta l'espressione lambda num => num < 5 (C#) o Function(num) num < 5 (Visual Basic) utilizzando i compilatori C# e Visual Basic.


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


Per creare strutture ad albero dell'espressione tramite l'API, utilizzare la classe Expression. Questa classe contiene metodi factory statici che creano nodi della struttura ad albero dell'espressione di tipi specifici, ad esempio ParameterExpression, che rappresenta una variabile o un parametro, o MethodCallExpression, che rappresenta una chiamata al metodo. ParameterExpression , MethodCallExpression e gli altri tipi specifici dell'espressione vengono inoltre definiti nello spazio dei nomi System.Linq.Expressions. Tali tipi derivano dal tipo astratto Expression.

Nell'esempio di codice seguente viene illustrato come creare una struttura ad albero dell'espressione che rappresenta l'espressione lambda num => num < 5 (C#) o Function(num) num < 5 (Visual Basic) tramite l'API.



            // Add the following using directive to your code file:
            // using System.Linq.Expressions;

            // Manually build the expression tree for 
            // the lambda expression num => num < 5.
            ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
            ConstantExpression five = Expression.Constant(5, typeof(int));
            BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
            Expression<Func<int, bool>> lambda1 =
                Expression.Lambda<Func<int, bool>>(
                    numLessThanFive,
                    new ParameterExpression[] { numParam });



In .NET Framework 4, l'API delle strutture ad albero dell'espressione supporta inoltre assegnazioni ed espressioni del flusso di controllo, quali cicli, blocchi condizionali e blocchi try-catch. Tramite l'API, è possibile creare strutture ad albero dell'espressione più complesse rispetto a quelle create dalle espressioni lambda mediante i compilatori C# e Visual Basic. Nell'esempio seguente viene illustrato come creare una struttura ad albero dell'espressione che calcola il fattoriale di un numero.


// Creating a parameter expression.
ParameterExpression value = Expression.Parameter(typeof(int), "value");

// Creating an expression to hold a local variable. 
ParameterExpression result = Expression.Parameter(typeof(int), "result");

// Creating a label to jump to from a loop.
LabelTarget label = Expression.Label(typeof(int));

// Creating a method body.
BlockExpression block = Expression.Block(
    // Adding a local variable.
    new[] { result },
    // Assigning a constant to a local variable: result = 1
    Expression.Assign(result, Expression.Constant(1)),
    // Adding a loop.
        Expression.Loop(
    // Adding a conditional block into the loop.
           Expression.IfThenElse(
    // Condition: value > 1
               Expression.GreaterThan(value, Expression.Constant(1)),
    // If true: result *= value --
               Expression.MultiplyAssign(result,
                   Expression.PostDecrementAssign(value)),
    // If false, exit the loop and go to the label.
               Expression.Break(label, result)
           ),
    // Label to jump to.
       label
    )
);

// Compile and execute an expression tree.
int factorial = Expression.Lambda<Func<int, int>>(block, value).Compile()(5);

Console.WriteLine(factorial);
// Prints 120.


Per ulteriori informazioni, vedere l'articolo relativo alla generazione di metodi dinamici con strutture ad albero dell'espressione in Visual Studio 2010 (la pagina potrebbe essere in inglese).

Nell'esempio di codice seguente viene illustrato come la struttura ad albero dell'espressione che rappresenta l'espressione lambda num => num < 5 (C#) o Function(num) num < 5 (Visual Basic) possa essere scomposta nelle relative parti.



// Add the following using directive to your code file:
// using System.Linq.Expressions;

// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;

// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;

Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
                  param.Name, left.Name, operation.NodeType, right.Value);

// This code produces the following output:

// Decomposed expression: num => num LessThan 5            


Le strutture ad albero dell'espressione devono essere immutabili. Ciò significa che se si desidera modificare una struttura ad albero dell'espressione, è necessario costruirne una nuova copiando quella esistente e sostituendone i nodi. Per attraversare la struttura ad albero dell'espressione esistente, è possibile utilizzare un visitatore della struttura a albero dell'espressione. Per ulteriori informazioni, vedere Procedura: modificare strutture ad albero dell'espressione (C# e Visual Basic).

Il tipo Expression<TDelegate> fornisce il metodo Compile che compila il codice rappresentato da una struttura ad albero dell'espressione in un delegato eseguibile.

Nell'esempio di codice seguente viene illustrato come compilare una struttura ad albero dell'espressione ed eseguire il codice risultante.


// Creating an expression tree.
Expression<Func<int, bool>> expr = num => num < 5;

// Compiling the expression tree into a delegate.
Func<int, bool> result = expr.Compile();

// Invoking the delegate and writing the result to the console.
Console.WriteLine(result(4));

// Prints True.

// You can also use simplified syntax
// to compile and run an expression tree.
// The following line can replace two previous statements.
Console.WriteLine(expr.Compile()(4));

// Also prints True.


Per ulteriori informazioni, vedere Procedura: eseguire alberi delle espressioni (C# e Visual Basic).

Aggiunte alla community

AGGIUNGI
Mostra:
© 2014 Microsoft