İfade Ağaçları (Visual Basic)
İfade ağaçları, her düğümün bir ifade olduğu ağaç benzeri bir veri yapısında kodu temsil eden bir yöntem çağrısı veya gibi ikili bir işlemdir x < y
.
İfade ağaçlarının temsil ettiği kodu derleyebilir ve çalıştırabilirsiniz. Bu, yürütülebilir kodun dinamik olarak değiştirilmesini, LINQ sorgularının çeşitli veritabanlarında yürütülmesini ve dinamik sorguların oluşturulmasını sağlar. LINQ'teki ifade ağaçları hakkında daha fazla bilgi için bkz. Nasıl yapılır: Dinamik Sorgular Oluşturmak için İfade Ağaçlarını Kullanma (Visual Basic).
İfade ağaçları, dinamik diller ile .NET Framework arasında birlikte çalışabilirlik sağlamak ve derleyici yazarlarının Microsoft ara dili (MSIL) yerine ifade ağaçlarını yaymasını sağlamak için dinamik dil çalışma zamanında (DLR) de kullanılır. DLR hakkında daha fazla bilgi için bkz. Dinamik Dil Çalışma Zamanına Genel Bakış.
C# veya Visual Basic derleyicisinin anonim lambda ifadesini temel alarak sizin için bir ifade ağacı oluşturmasını sağlayabilir veya ad alanını kullanarak System.Linq.Expressions el ile ifade ağaçları oluşturabilirsiniz.
Lambda İfadelerinden İfade Ağaçları Oluşturma
Türünde bir değişkene Expression<TDelegate>bir lambda ifadesi atandığında, derleyici lambda ifadesini temsil eden bir ifade ağacı oluşturmak için kod yayar.
Visual Basic derleyicisi yalnızca ifade lambdalarından (veya tek satırlı lambdalardan) ifade ağaçları oluşturabilir. Deyimi lambdaları (veya çok satırlı lambdaları) ayrıştıramaz. Visual Basic lambda ifadeleri hakkında daha fazla bilgi için bkz. Lambda İfadeleri.
Aşağıdaki kod örnekleri, Visual Basic derleyicisinin lambda ifadesini Function(num) num < 5
temsil eden bir ifade ağacı oluşturmasını nasıl sağladıklarını gösterir.
Dim lambda As Expression(Of Func(Of Integer, Boolean)) =
Function(num) num < 5
API Kullanarak İfade Ağaçları Oluşturma
API kullanarak ifade ağaçları oluşturmak için sınıfını Expression kullanın. Bu sınıf, belirli türlerde ifade ağacı düğümleri oluşturan statik fabrika yöntemleri içerir; örneğin, ParameterExpressionbir değişkeni veya parametreyi temsil eden ya da MethodCallExpressionbir yöntem çağrısını temsil eden . ParameterExpression, MethodCallExpressionve ifadeye özgü diğer türler de ad alanında System.Linq.Expressions tanımlanır. Bu türler soyut türünden Expressiontüretilir.
Aşağıdaki kod örneği, API kullanarak lambda ifadesini temsil eden bir ifade Function(num) num < 5
ağacının nasıl oluşturulacağını gösterir.
' 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})
.NET Framework 4 veya sonraki sürümlerde, ifade ağaçları API'si döngüler, koşullu bloklar ve bloklar gibi atamaları ve try-catch
denetim akışı ifadelerini de destekler. API'yi kullanarak, Visual Basic derleyicisi tarafından lambda ifadelerinden oluşturulabileceklerden daha karmaşık ifade ağaçları oluşturabilirsiniz. Aşağıdaki örnekte, bir sayının faktöriyelini hesaplayan bir ifade ağacının nasıl oluşturulacağı gösterilmektedir.
' 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.
Daha fazla bilgi için bkz. Visual Studio sonraki sürümleri için de geçerli olan Visual Studio 2010'da İfade Ağaçları ile Dinamik Yöntemler Oluşturma.
İfade Ağaçlarını Ayrıştırma
Aşağıdaki kod örneği, lambda ifadesini Function(num) num < 5
temsil eden ifade ağacının bölümlerine nasıl ayrıştırılabildiğini gösterir.
' 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
İfade Ağaçlarının Değişmezliği
İfade ağaçları sabit olmalıdır. Başka bir deyişle, bir ifade ağacını değiştirmek istiyorsanız, var olan ağacı kopyalayıp içindeki düğümleri değiştirerek yeni bir ifade ağacı oluşturmanız gerekir. Varolan ifade ağacından geçiş yapmak için bir ifade ağacı ziyaretçisi kullanabilirsiniz. Daha fazla bilgi için bkz. Nasıl yapılır: İfade Ağaçlarını Değiştirme (Visual Basic).
İfade Ağaçlarını Derleme
türü, Expression<TDelegate> bir ifade ağacı tarafından temsil edilen kodu yürütülebilir bir temsilcide derleyen yöntemi sağlar Compile .
Aşağıdaki kod örneğinde, bir ifade ağacının nasıl derlenip sonuçta elde edilen kodun nasıl çalıştırılması gösterilmektedir.
' 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.
Daha fazla bilgi için bkz. Nasıl yapılır: İfade Ağaçlarını Yürütme (Visual Basic).