Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Stromy výrazů představují kód ve stromové datové struktuře, kde každý uzel je výraz, například volání metody nebo binární operace, například x < y.
Kód reprezentovaný stromy výrazů můžete zkompilovat a spustit. To umožňuje dynamickou úpravu spustitelného kódu, provádě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 Postupy: Použití stromů výrazů k vytváření dynamických dotazů (Visual Basic).
Stromy výrazů se také používají v modulu RUNTIME dynamického jazyka (DLR) k zajištění interoperability mezi dynamickými jazyky a rozhraním .NET Framework a k povolení zapisovačů kompilátoru generovat stromy výrazů místo společného zprostředkujícího jazyka (CIL). Další informace o DLR najdete v části Přehled modulu dynamického jazykového runtime.
Můžete mít kompilátor jazyka C# nebo Visual Basic, který vám vytvoří strom výrazů na základě anonymního výrazu lambda, nebo stromy výrazů můžete vytvořit ručně pomocí System.Linq.Expressions oboru názvů.
Vytváření stromů výrazů ze syntaxí lambda
Pokud je výraz lambda přiřazen k proměnné typu Expression<TDelegate>, kompilátor generuje kód pro sestavení stromu výrazu, který představuje výraz lambda.
Kompilátor jazyka Visual Basic může generovat stromy výrazů pouze z výrazů lambda (nebo jednořádkových lambda). Nemůže analyzovat výrazy lambda (nebo víceřádkové lambda). Další informace o výrazech lambda v jazyce Visual Basic naleznete v tématu Výrazy lambda.
Následující příklady kódu ukazují, jak nechat kompilátor jazyka Visual Basic vytvořit strom výrazů, který reprezentuje lambda výraz 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
Pokud chcete vytvořit stromy výrazů pomocí rozhraní API, použijte Expression třídu. Tato třída obsahuje statické metody, které vytvářejí uzly stromu výrazů konkrétních typů, například ParameterExpression, které představují proměnnou nebo parametr, nebo MethodCallExpression, který představuje volání metody. ParameterExpression, MethodCallExpression, a další typy specifické pro výraz jsou také definovány v oboru názvů System.Linq.Expressions. Tyto typy jsou odvozeny od abstraktního typu Expression.
Následující příklad kódu ukazuje, jak vytvořit strom výrazu, který představuje výraz Function(num) num < 5 lambda 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 rozhraní .NET Framework 4 nebo novějším rozhraní API stromů výrazů také podporuje přiřazení a výrazy toku ří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ž stromy, které lze vytvořit z výrazů lambda kompilátorem jazyka 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 sadě Visual Studio 2010, které platí také pro novější verze sady Visual Studio.
Analýza stromů výrazů
Následující příklad kódu ukazuje, jak strom výrazu, který představuje výraz lambda Function(num) num < 5 lze rozdělit do jeho částí.
' 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ěnnost stromů výrazů
Stromy výrazů by měly být neměnné. To znamená, že pokud chcete upravit strom výrazů, musíte vytvořit nový strom výrazu zkopírováním existujícího stromu a nahrazením uzlů v něm. Návštěvník stromu výrazů můžete použít k procházení existujícího stromu výrazů. Další informace naleznete v tématu Postupy: Úprava stromů výrazů (Visual Basic).
Kompilace stromů výrazů
Typ Expression<TDelegate> poskytuje metodu Compile , která kompiluje kód reprezentovaný stromem výrazu do spustitelného delegáta.
Následující příklad kódu ukazuje, jak zkompilovat strom výrazů 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 naleznete v tématu Postupy: Spouštění stromů výrazů (Visual Basic).