Dela via


Uttrycksträd (Visual Basic)

Uttrycksträd representerar kod i en trädliknande datastruktur, där varje nod är ett uttryck, till exempel ett metodanrop eller en binär åtgärd som x < y.

Du kan kompilera och köra kod som representeras av uttrycksträd. Detta möjliggör dynamisk ändring av körbar kod, körning av LINQ-frågor i olika databaser och skapandet av dynamiska frågor. Mer information om uttrycksträd i LINQ finns i How to: Use Expression Trees to Build Dynamic Queries (Visual Basic).

Uttrycksträd används också i DLR (Dynamic Language Runtime) för att ge samverkan mellan dynamiska språk och .NET Framework och för att göra det möjligt för kompilatorskrivare att generera uttrycksträd i stället för Microsofts mellanliggande språk (MSIL). Mer information om DLR finns i Översikt över dynamisk språkkörning.

Du kan låta kompilatorn C# eller Visual Basic skapa ett uttrycksträd baserat på ett anonymt lambda-uttryck, eller så kan du skapa uttrycksträd manuellt med hjälp System.Linq.Expressions av namnområdet.

Skapa uttrycksträd från Lambda-uttryck

När ett lambda-uttryck tilldelas till en variabel av typen Expression<TDelegate>genererar kompilatorn kod för att skapa ett uttrycksträd som representerar lambda-uttrycket.

Den Visual Basic kompilatorn kan endast generera uttrycksträd från uttrycket lambdas (eller lambdas med en rad). Det går inte att parsa instruktionen lambdas (eller lambdas med flera rader). Mer information om lambda-uttryck i Visual Basic finns i Lambda-uttryck.

Följande kodexempel visar hur du får Visual Basic kompilatorn att skapa ett uttrycksträd som representerar lambda-uttrycket Function(num) num < 5.

Dim lambda As Expression(Of Func(Of Integer, Boolean)) =  
    Function(num) num < 5  

Skapa uttrycksträd med hjälp av API:et

Om du vill skapa uttrycksträd med hjälp av API:et använder du Expression klassen . Den här klassen innehåller statiska fabriksmetoder som skapar uttrycksträdsnoder av specifika typer, ParameterExpressiontill exempel , som representerar en variabel eller parameter, eller MethodCallExpression, som representerar ett metodanrop. ParameterExpression, MethodCallExpressionoch de andra uttrycksspecifika typerna definieras också i System.Linq.Expressions namnområdet. Dessa typer härleds från den abstrakta typen Expression.

Följande kodexempel visar hur du skapar ett uttrycksträd som representerar lambda-uttrycket Function(num) num < 5 med hjälp av API:et.

' Import the following namespace to your project: System.Linq.Expressions  
  
' Manually build the expression tree for the lambda expression num => num < 5.  
Dim numParam As ParameterExpression = Expression.Parameter(GetType(Integer), "num")  
Dim five As ConstantExpression = Expression.Constant(5, GetType(Integer))  
Dim numLessThanFive As BinaryExpression = Expression.LessThan(numParam, five)  
Dim lambda1 As Expression(Of Func(Of Integer, Boolean)) =  
  Expression.Lambda(Of Func(Of Integer, Boolean))(  
        numLessThanFive,  
        New ParameterExpression() {numParam})  

I .NET Framework 4 eller senare stöder API:et för uttrycksträd även tilldelningar och kontrollflödesuttryck som loopar, villkorsblock och try-catch block. Med hjälp av API:et kan du skapa uttrycksträd som är mer komplexa än de som kan skapas från lambda-uttryck av Visual Basic-kompilatorn. I följande exempel visas hur du skapar ett uttrycksträd som beräknar faktorn för ett tal.

' Creating a parameter expression.  
Dim value As ParameterExpression =  
    Expression.Parameter(GetType(Integer), "value")  
  
' Creating an expression to hold a local variable.
Dim result As ParameterExpression =  
    Expression.Parameter(GetType(Integer), "result")  
  
' Creating a label to jump to from a loop.  
Dim label As LabelTarget = Expression.Label(GetType(Integer))  
  
' Creating a method body.  
Dim block As BlockExpression = Expression.Block(  
    New ParameterExpression() {result},  
    Expression.Assign(result, Expression.Constant(1)),  
    Expression.Loop(  
        Expression.IfThenElse(  
            Expression.GreaterThan(value, Expression.Constant(1)),  
            Expression.MultiplyAssign(result,  
                Expression.PostDecrementAssign(value)),  
            Expression.Break(label, result)  
        ),  
        label  
    )  
)  
  
' Compile an expression tree and return a delegate.  
Dim factorial As Integer =  
    Expression.Lambda(Of Func(Of Integer, Integer))(block, value).Compile()(5)  
  
Console.WriteLine(factorial)  
' Prints 120.  

Mer information finns i Generera dynamiska metoder med uttrycksträd i Visual Studio 2010, som även gäller för senare versioner av Visual Studio.

Parsa uttrycksträd

Följande kodexempel visar hur uttrycksträdet som representerar lambda-uttrycket Function(num) num < 5 kan delas upp i dess delar.

' Import the following namespace to your project: System.Linq.Expressions  
  
' Create an expression tree.  
Dim exprTree As Expression(Of Func(Of Integer, Boolean)) = Function(num) num < 5  
  
' Decompose the expression tree.  
Dim param As ParameterExpression = exprTree.Parameters(0)  
Dim operation As BinaryExpression = exprTree.Body  
Dim left As ParameterExpression = operation.Left  
Dim right As ConstantExpression = operation.Right  
  
Console.WriteLine(String.Format("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  

Oföränderlighet för uttrycksträd

Uttrycksträd bör vara oföränderliga. Det innebär att om du vill ändra ett uttrycksträd måste du skapa ett nytt uttrycksträd genom att kopiera det befintliga och ersätta noder i det. Du kan använda en besökare i uttrycksträdet för att bläddra i det befintliga uttrycksträdet. Mer information finns i How to: Modify Expression Trees (Visual Basic).

Kompilera uttrycksträd

Typen Expression<TDelegate> innehåller den Compile metod som kompilerar koden som representeras av ett uttrycksträd till ett körbart ombud.

Följande kodexempel visar hur du kompilerar ett uttrycksträd och kör den resulterande koden.

' Creating an expression tree.  
Dim expr As Expression(Of Func(Of Integer, Boolean)) =  
    Function(num) num < 5  
  
' Compiling the expression tree into a delegate.  
Dim result As Func(Of Integer, Boolean) = 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.  

Mer information finns i Så här kör du uttrycksträd (Visual Basic).

Se även