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 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 < 5ké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).

Lásd még