Comment : modifier des arborescences d'expression (C# et Visual Basic)
Cette rubrique vous indique comment modifier une arborescence d'expression. Les arborescences d'expression sont immuables, ce qui signifie qu'elles ne peuvent pas être modifiées directement. Pour modifier une arborescence d'expression, vous devez créer une copie d'une arborescence d'expression existante et, lorsque vous créez la copie, apporter les modifications requises. Vous pouvez utiliser la classe ExpressionVisitor pour parcourir une arborescence d'expression existante et copier chaque nœud visité.
Notes
Vous pouvez trouver le code source de la classe ExpressionVisitor sur le site Web CodePlex (page éventuellement en anglais).
Pour modifier une arborescence d'expression
Dans Visual Studio, créez un projet Application console.
Ajoutez la classe AndAlsoModifier à votre projet.
Cette classe hérite de la classe ExpressionVisitor et est spécialisée pour modifier les expressions qui représentent des opérations AND conditionnelles. Elle fait passer ces opérations d'un AND conditionnel à un OR conditionnel. Pour ce faire, la classe substitue la méthode VisitBinary du type de base, car les expressions AND conditionnelles sont représentées comme expressions binaires. Dans la méthode VisitBinary, si l'expression qui lui est passée représente une opération AND conditionnelle, le code construit une nouvelle expression qui contient l'opérateur OR conditionnel au lieu de l'opérateur AND conditionnel. Si l'expression passée à VisitBinary ne représente pas d'opération AND conditionnelle, la méthode diffère à l'implémentation de la classe de base. Les méthodes de la classe de base construisent des nœuds qui sont semblables aux arborescences d'expression passées, mais les sous-arbres des nœuds sont remplacés par les arborescences d'expression produites de manière récursive par le visiteur.
Ajoutez une directive using (ou une instruction Imports en Visual Basic) au fichier pour l'espace de noms System.Linq.Expressions.
Public Class AndAlsoModifier Inherits ExpressionVisitor Public Function Modify(ByVal expr As Expression) As Expression Return Visit(expr) End Function Protected Overrides Function VisitBinary(ByVal b As BinaryExpression) As Expression If b.NodeType = ExpressionType.AndAlso Then Dim left = Me.Visit(b.Left) Dim right = Me.Visit(b.Right) ' Make this binary expression an OrElse operation instead ' of an AndAlso operation. Return Expression.MakeBinary(ExpressionType.OrElse, left, right, _ b.IsLiftedToNull, b.Method) End If Return MyBase.VisitBinary(b) End Function End Class
public class AndAlsoModifier : ExpressionVisitor { public Expression Modify(Expression expression) { return Visit(expression); } protected override Expression VisitBinary(BinaryExpression b) { if (b.NodeType == ExpressionType.AndAlso) { Expression left = this.Visit(b.Left); Expression right = this.Visit(b.Right); // Make this binary expression an OrElse operation instead of an AndAlso operation. return Expression.MakeBinary(ExpressionType.OrElse, left, right, b.IsLiftedToNull, b.Method); } return base.VisitBinary(b); } }
Ajoutez du code à la méthode Main dans le fichier Program.cs (Module1.vb dans Visual Basic) pour créer une arborescence d'expression et passez-la à la méthode qui la modifiera.
Le code suivant crée une expression qui contient une opération AND conditionnelle. Il crée alors une instance de la classe AndAlsoModifier et passe l'expression à la méthode Modify de cette classe. L'arborescence d'expression d'origine et l'arborescence d'expression modifiée sont toutes deux sorties pour afficher la modification.
Ajoutez une directive using (ou une instruction Imports en Visual Basic) au fichier pour l'espace de noms System.Linq.Expressions.
Dim expr As Expression(Of Func(Of String, Boolean)) = _ Function(name) name.Length > 10 AndAlso name.StartsWith("G") Console.WriteLine(expr) Dim modifier As New AndAlsoModifier() Dim modifiedExpr = modifier.Modify(CType(expr, Expression)) Console.WriteLine(modifiedExpr) ' This code produces the following output: ' name => ((name.Length > 10) && name.StartsWith("G")) ' name => ((name.Length > 10) || name.StartsWith("G"))
Expression<Func<string, bool>> expr = name => name.Length > 10 && name.StartsWith("G"); Console.WriteLine(expr); AndAlsoModifier treeModifier = new AndAlsoModifier(); Expression modifiedExpr = treeModifier.Modify((Expression) expr); Console.WriteLine(modifiedExpr); /* This code produces the following output: name => ((name.Length > 10) && name.StartsWith("G")) name => ((name.Length > 10) || name.StartsWith("G")) */
Compilez et exécutez l'application.
Voir aussi
Tâches
Comment : exécuter des arborescences d'expression (C# et Visual Basic)