Como: Modificar árvores de expressão
Este tópico mostra como modificar uma árvore de expressão.Árvores de expressão são imutáveis, o que significa que eles não podem ser modificados diretamente.Para alterar uma árvore de expressões, você deve criar uma cópia de uma árvore de expressão existente e quando você cria a cópia, faça as alterações necessárias.Você pode usar um visitante da árvore de expressão para percorrer uma árvore de expressões existentes e copiar cada nó em que ele visita.
Para modificar uma árvore de expressão
In Visual Studio, crie um novo Aplicativo de consoleprojeto .
Adicione uma referência a sistema.Core.dll, se ele já não é referenciado.
Adicionar o ExpressionVisitor classe para seu projeto.
Este código está disponível em Como: Implementar um visitante de árvore de expressões.
Add using diretivas (ou Imports instruções no Visual Basic) o arquivo para os namespaces a seguir: sistema.Collections.Generic, sistema.Collections.ObjectModel e sistema.Linq.Expressions.
Adicionar o AndAlsoModifier classe para seu projeto.
Esta classe herda o ExpressionVisitor classe e especializados para modificar as expressões que representam condicional AND operações. Ele altera essas operações por uma condicional AND para uma condicional OR. Para fazer isso, a classe substitui o VisitBinary método do tipo de base, porque condicional AND expressões são representados sistema autônomo expressões binário. No VisitBinary método, se a expressão que é passada para ele representa uma condicional AND operação, o código cria uma nova expressão que contém o condicional OR operador em vez do condicional AND operador. Se a expressão que é passada para VisitBinary não representa uma condicional AND operação, o método passa para a implementação da classe base. Os métodos da classe base construção nós que são semelhantes as árvores de expressão são passados em, mas os nós têm suas árvores de sub-rotina substituídas pelas árvores de expressão são produzidos recursivamente pelo visitante.
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); } }
Adicionar um using diretiva (ou Imports demonstrativo no Visual Basic) o arquivo para o namespace sistema.Linq.Expressions.
Adicione código para o Main método no arquivo programa.cs (Module1.vb no Visual Basic) para criar uma árvore de expressões e passá-lo para o método que irá modificá-lo.
O código a seguir cria uma expressão que contenha um condicional AND operação. Ele então cria uma instância do AndAlsoModifier classe e passa a expressão para o Modify método dessa classe. O original e as árvores de expressão modificada são saídas para mostrar a alterar.
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")) */
Adicionar um using diretiva (ou Imports demonstrativo no Visual Basic) o arquivo para o namespace sistema.Linq.Expressions.
Compile e execute o aplicativo.
Consulte também
Tarefas
Como: Executar árvores de expressão
Demonstra Passo a passo: Criar um provedor de LINQ IQueryable
Como: Implementar um visitante de árvore de expressões