Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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 tillhandahålla 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 ett gemensamt mellanliggande språk (CIL). För mer information om DLR, se Översikt av dynamisk språkkörningsmiljö.
Du kan låta kompilatorn C# eller Visual Basic skapa ett uttrycksträd för dig 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 en variabel av typen Expression<TDelegate>genererar kompilatorn kod för att skapa ett uttrycksträd som representerar lambda-uttrycket.
Visual Basic-kompilatorn kan endast generera uttrycksträd genom uttryckslambda-uttryck (eller enrads lambda-uttryck). Det går inte att parsa deklarations-lambdas (eller flerrads-lambdas). 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ädnoder av specifika typer, ParameterExpressiontill exempel , som representerar en variabel eller parameter, eller MethodCallExpression, som representerar ett metodanrop. ParameterExpression, MethodCallExpression, och 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.
Parsning av 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 uttrycksträdsbesökare för att traversera det befintliga uttrycksträdet. Mer information finns i How to: Modify Expression Trees (Visual Basic).
Kompilera uttrycksträd
Typen Expression<TDelegate> innehåller Compile-metoden som kompilerar koden representerad av ett uttrycksträd till en körbar delegering.
I följande kodexempel visas 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 How to: Execute Expression Trees (Visual Basic).