Megosztás a következőn keresztül:


Kifejezésfák (Visual Basic)

A kifejezésfák egy faszerű adatstruktúrában lévő kódot jelölnek, ahol minden csomópont kifejezés, például metódushívás vagy bináris művelet, például x < y.

A kifejezésfák által képviselt 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. A LINQ kifejezésfáival kapcsolatos további információkért lásd: A kifejezésfák használata dinamikus lekérdezések (Visual Basic) létrehozásához.

A dinamikus nyelvi futtatókörnyezetben (DLR) kifejezésfákat is használnak a dinamikus nyelvek és a .NET-keretrendszer közötti interoperabilitás biztosítására, és lehetővé teszik a fordítók számára, hogy kifejezésfákat bocsátanak ki a közös köztes nyelv (CIL) helyett. A DLR-ről további információt a Dinamikus nyelvi futtatókörnyezet áttekintése című témakörben talál.

A C# vagy a 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 egy lambda kifejezés egy típusú Expression<TDelegate>változóhoz van rendelve, a fordító kódot bocsát ki a lambda kifejezést jelképező kifejezésfa létrehozásához.

A Visual Basic fordító csak a lambdas kifejezésből (vagy egysoros lambdákból) tud kifejezésfákat létrehozni. Nem tudja elemezni az utasítás lambda kifejezéseket (vagy többsoros lambda kifejezéseket). További információ a Lambda-kifejezésekről a Visual Basicben: Lambda Expressions.

Az alábbi példakód bemutatja, hogyan hozhat létre a Visual Basic fordító egy olyan kifejezésfát, amely a lambda kifejezést Function(num) num < 5jelöli.

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 jelképező kifejezésfacsomópontokat. 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 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 folyamatkifejezések vezérlését 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 a Lambda-kifejezésekből a Visual Basic fordító által létrehozottaknál. 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, hogy a lambda kifejezést Function(num) num < 5 jelképező kifejezésfa hogyan bontható fel annak 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óknak 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 bejáró segítségével bejárhatja a meglévő kifejezésfát. További információt a Kifejezésfák módosítása (Visual Basic) című témakörben talál.

Kifejezésfák összeállítása

A Expression<TDelegate> típus biztosítja a Compile metódust, amely a kifejezésfával ábrázolt kódot végrehajtható delegálttá fordítja.

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óért lásd: Kifejezésfák végrehajtása (Visual Basic).

Lásd még