Stromy výrazů (Visual Basic)
Stromy výrazů reprezentují kód v datové struktuře podobné stromu, kde každý uzel je výraz, například volání metody nebo binární operace, jako je například x < y .
Můžete zkompilovat a spustit kód reprezentovaný stromy výrazů. To umožňuje dynamickou úpravu spustitelného kódu, spuštění dotazů LINQ v různých databázích a vytváření dynamických dotazů. Další informace o stromech výrazů v LINQ naleznete v tématu How to: use Expression Trees to Dynamic dotazy (Visual Basic).
stromy výrazů se používají také v dynamickém jazykovém modulu runtime (DLR) k zajištění interoperability mezi dynamickými jazyky a .NET Framework a umožňují zapisovačům kompilátoru vysílat stromy výrazů namísto jazyka MSIL (Microsoft intermediate language). Další informace o DLR najdete v tématu Přehled dynamického jazykového modulu runtime.
můžete mít kompilátor C# nebo Visual Basic vytvořit strom výrazu pro vás na základě anonymního výrazu lambda, nebo můžete vytvořit stromy výrazů ručně pomocí System.Linq.Expressions oboru názvů.
Vytváření stromů výrazů ze výrazů lambda
Když je výraz lambda přiřazen proměnné typu Expression<TDelegate> , kompilátor generuje kód pro sestavení stromu výrazu, který reprezentuje lambda výraz.
kompilátor Visual Basic může generovat stromy výrazů pouze z výrazů lambda výrazů (nebo jednoduchých výrazů lambda). Nelze analyzovat výrazy lambda příkazů (nebo víceřádkové výrazy lambda). další informace o výrazech lambda v Visual Basic naleznete v tématu lambda expressions.
následující příklady kódu ukazují, jak má kompilátor Visual Basic vytvořit strom výrazu, který představuje výraz lambda Function(num) num < 5 .
Dim lambda As Expression(Of Func(Of Integer, Boolean)) =
Function(num) num < 5
Vytváření stromů výrazů pomocí rozhraní API
Chcete-li vytvořit stromy výrazů pomocí rozhraní API, použijte Expression třídu. Tato třída obsahuje statické metody továrny, které vytvářejí uzly stromu výrazů specifických typů, například ParameterExpression , které představují proměnnou nebo parametr, nebo MethodCallExpression , které představují volání metody. ParameterExpression, MethodCallExpression a další typy specifické pro výraz jsou také definovány v System.Linq.Expressions oboru názvů. Tyto typy jsou odvozeny z abstraktního typu Expression .
Následující příklad kódu ukazuje, jak vytvořit strom výrazu, který reprezentuje lambda výraz Function(num) num < 5 pomocí rozhraní API.
' 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})
v .NET Framework 4 nebo novějších rozhraní API stromů výrazů podporuje také přiřazení a vývojové výrazy řízení, jako jsou smyčky, podmíněné bloky a try-catch bloky. pomocí rozhraní API můžete vytvořit stromy výrazů, které jsou složitější než ty, které lze vytvořit z výrazů lambda kompilátorem Visual Basic. Následující příklad ukazuje, jak vytvořit strom výrazu, který vypočítá faktoriál čísla.
' 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.
další informace naleznete v tématu generování dynamických metod pomocí stromů výrazů v Visual Studio 2010, které platí také pro novější verze Visual Studio.
Analýza stromů výrazů
Následující příklad kódu ukazuje, jak je možné rozložit strom výrazu reprezentující výraz lambda Function(num) num < 5 na jeho části.
' 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
Neměnnosti stromů výrazů
Stromy výrazů by měly být neměnné. To znamená, že pokud chcete upravit strom výrazu, je nutné vytvořit nový strom výrazu zkopírováním stávajícího a nahrazením uzlů v něm. K procházení stávajícího stromu výrazů můžete použít návštěvníka stromu výrazu. Další informace najdete v tématu Postup: Změna stromů výrazů (Visual Basic).
Kompilování stromů výrazů
Expression<TDelegate>Typ poskytuje Compile metodu, která zkompiluje kód reprezentovaný stromem výrazu do delegáta spustitelného souboru.
Následující příklad kódu ukazuje, jak zkompilovat strom výrazu a spustit výsledný kód.
' 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.
Další informace najdete v tématu Postup: spuštění stromů výrazů (Visual Basic).