Exporter (0) Imprimer
Développer tout
Cet article a fait l'objet d'une traduction manuelle. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source

Arborescences d'expression (C# et Visual Basic)

Les arborescences d'expressions représentent du code dans une structure de données arborescente, où chaque nœud est une expression, par exemple un appel de méthode ou une opération binaire comme x < y.

Vous pouvez compiler et exécuter du code représenté par des arborescences d'expressions. Ceci permet la modification dynamique du code exécutable, l'exécution de requêtes LINQ dans différentes bases de données et la création de requêtes dynamiques. Pour plus d'informations sur les arborescences d'expressions dans LINQ, consultez Comment : utiliser des arborescences d'expression pour générer des requêtes dynamiques (C# et Visual Basic).

Les arborescences d'expressions sont également utilisées dans l'environnement d'exécution de langage dynamique (DLR, Dynamic Language Runtime) pour fournir une interopérabilité entre les langages dynamiques et .NET Framework, ainsi que pour permettre aux writers de compilateur d'émettre des arborescences d'expressions au lieu d'utiliser le langage intermédiaire MSIL (Microsoft Intermediate Language). Pour plus d'informations sur le DLR, consultez Vue d'ensemble du Dynamic Language Runtime.

Le compilateur C# ou Visual Basic peut créer pour vous une arborescence d'expressions basée sur une expression lambda anonyme. Vous pouvez aussi créer manuellement des arborescences d'expressions en utilisant l'espace de noms System.Linq.Expressions.

Quand une expression lambda est affectée à une variable de type Expression<TDelegate>, le compilateur produit du code pour générer une arborescence d'expressions qui représente l'expression lambda.

Les compilateurs C# et Visual Basic peuvent générer des arborescences d'expressions seulement à partir d'expressions lambda (ou de lambdas sur une seule ligne). Ils ne peuvent pas analyser des lambdas d'instruction (ou lambdas multilignes). Pour plus d'informations sur les expressions lambda en C#, consultez Expressions lambda (Guide de programmation C#). Pour Visual Basic, consultez Expressions lambda (Visual Basic).

Les exemples de code suivants montrent comment les compilateurs C# et Visual Basic créent une arborescence d'expressions qui représente l'expression lambda num => num < 5 (C#) ou Function(num) num < 5 (Visual Basic).


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


Pour créer des arborescences d'expressions à l'aide de l'API, utilisez la classe Expression. Cette classe contient des méthodes de fabrique statiques qui créent des nœuds d'arborescence d'expressions de types spécifiques, par exemple ParameterExpression, qui représente une variable ou un paramètre, ou MethodCallExpression, qui représente un appel de méthode. ParameterExpression , MethodCallExpression et les autres types spécifiques à une expression sont également définis dans l'espace de noms System.Linq.Expressions. Ces types dérivent du type abstrait Expression.

L'exemple de code suivant montre comment créer une arborescence d'expressions qui représente l'expression lambda num => num < 5 (C#) ou Function(num) num < 5 (Visual Basic) à l'aide de 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 });



Dans .NET Framework 4, l'API de l'arborescence d'expressions prend également en charge les affectations et les expressions de flux de contrôle, comme les boucles, les blocs conditionnels et les blocs try-catch. À l'aide de l'API, vous pouvez créer des arborescences d'expressions qui sont plus complexes que celles qui peuvent être créées à partir d'expressions lambda par les compilateurs C# et Visual Basic. L'exemple suivant montre comment créer une arborescence d'expressions qui calcule la factorielle d'un nombre.


// 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.


Pour plus d'informations, consultez Génération de méthodes dynamiques avec des arborescences d'expressions dans Visual Studio 2010.

L'exemple de code suivant montre comment l'arborescence d'expressions qui représente l'expression lambda num => num < 5 (C#) ou Function(num) num < 5 (Visual Basic) peut être décomposée selon ses différentes parties.



// 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            


Les arborescences d'expressions doivent être immuables. Cela signifie que si vous voulez modifier une arborescence d'expressions, vous devez construire une nouvelle arborescence d'expressions en copiant l'arborescence existante et en y remplaçant les nœuds. Vous pouvez utiliser un visiteur d'arborescence d'expressions pour parcourir l'arborescence d'expressions existante. Pour plus d'informations, consultez Comment : modifier des arborescences d'expression (C# et Visual Basic).

Le type Expression<TDelegate> fournit la méthode Compile qui compile le code représenté par une arborescence d'expressions en un délégué exécutable.

L'exemple de code suivant montre comment compiler une arborescence d'expressions et exécuter le code résultant.


// 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.


Pour plus d'informations, consultez Comment : exécuter des arborescences d'expression (C# et Visual Basic).

Ajouts de la communauté

AJOUTER
Afficher:
© 2015 Microsoft