Kifejezésfák (Visual Basic)
A kifejezésfák egy faszerű adatstruktúrában lévő kódot jelölnek, ahol minden csomópont egy kifejezés, például egy metódushívás vagy egy bináris művelet, például x < y
.
A kifejezésfákkal ábrázolt kódot lefordíthatja és futtathatja. Ez lehetővé teszi a végrehajtható kód dinamikus módosítását, a LINQ-lekérdezések végrehajtását különböző adatbázisokban, valamint dinamikus lekérdezések létrehozását. További információ a LINQ kifejezésfáiról: How to: Use Expression Trees to Build Dynamic Queries (Visual Basic).
A dinamikus nyelvi futtatókörnyezetben (DLR) kifejezésfákat is használnak a dinamikus nyelvek és a .NET-keretrendszer közötti együttműködés biztosításához, valamint annak érdekében, hogy a fordítóírók kifejezésfákat bocsáthassanak ki a Microsoft köztes nyelve (MSIL) helyett. A DLR-ről további információt a Dynamic Language Runtime áttekintésében talál.
A C# vagy Visual Basic fordító létrehozhat egy kifejezésfát egy névtelen lambda kifejezés alapján, vagy manuálisan is létrehozhat kifejezésfákat a System.Linq.Expressions névtér használatával.
Kifejezésfák létrehozása Lambda-kifejezésekből
Ha lambda kifejezést rendel egy változótípushoz Expression<TDelegate>, a fordító kódot bocsát ki a lambda kifejezést képviselő kifejezésfa létrehozásához.
A Visual Basic fordító csak lambda kifejezésből (vagy egysoros lambdasból) tud kifejezésfákat létrehozni. Nem tudja elemezni a lambdas (vagy többsoros lambdas) utasítást. Az Visual Basic lambda kifejezéseiről további információt a Lambda-kifejezések című témakörben talál.
Az alábbi példakódok bemutatják, hogyan hozhat létre a Visual Basic fordító egy, a lambda kifejezést Function(num) num < 5
képviselő kifejezésfát.
Dim lambda As Expression(Of Func(Of Integer, Boolean)) =
Function(num) num < 5
Kifejezésfák létrehozása az API használatával
Ha kifejezésfákat szeretne létrehozni az API használatával, használja az osztályt Expression . Ez az osztály olyan statikus gyári metódusokat tartalmaz, amelyek adott típusú kifejezésfacsomópontokat hoznak létre, ParameterExpressionpéldául egy változót vagy paramétert, vagy MethodCallExpressionegy metódushívást jelölő csomópontot. ParameterExpression, MethodCallExpressionés a többi kifejezésspecifikus típus is definiálva van a System.Linq.Expressions névtérben. Ezek a típusok az absztrakt típusból Expressionszármaznak.
Az alábbi példakód bemutatja, hogyan hozhat létre egy olyan kifejezésfát, amely a lambda kifejezést Function(num) num < 5
jelöli az API használatával.
' 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})
A .NET-keretrendszer 4-es vagy újabb verzióiban a kifejezésfa API a hozzárendeléseket és a vezérlési folyamat kifejezéseit is támogatja, például hurkokat, feltételes blokkokat és try-catch
blokkokat. Az API használatával olyan kifejezésfákat hozhat létre, amelyek összetettebbek, mint amelyeket a Visual Basic-fordító lambda kifejezésekből hozhat létre. Az alábbi példa bemutatja, hogyan hozhat létre olyan kifejezésfát, amely kiszámítja egy szám faktoriálisát.
' 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.
További információ: Dinamikus metódusok létrehozása kifejezésfákkal a Visual Studio 2010-ben, amely a Visual Studio későbbi verzióira is vonatkozik.
Kifejezésfák elemzése
Az alábbi példakód bemutatja, hogyan bontható fel a lambda kifejezést Function(num) num < 5
képviselő kifejezésfa a részeire.
' 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
A kifejezésfák nem módosíthatók
A kifejezésfáknak nem módosíthatónak kell lenniük. Ez azt jelenti, hogy ha módosítani szeretne egy kifejezésfát, új kifejezésfát kell létrehoznia a meglévő másolásával és a benne lévő csomópontok cseréjével. A kifejezésfa látogatója segítségével bejárást végezhet a meglévő kifejezésfán. További információ: How to: Modify Expression Trees (Visual Basic).
Kifejezésfák fordítása
Ez Expression<TDelegate> a típus biztosítja azt a Compile metódust, amely lefordítja a kifejezésfa által képviselt kódot egy végrehajtható delegáltra.
Az alábbi példakód bemutatja, hogyan fordíthat le egy kifejezésfát, és hogyan futtathatja az eredményként kapott kódot.
' 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.
További információ: How to: Execute Expression Trees (Visual Basic).