مشاركة عبر


أشجار التعبير (C# و Visual Basic)

تمثل أشجار التعبير تعليمات برمجية في شجرة - مثل بنية بيانات أين أن كل عقدة تعبير على سبيل المثال أو استدعاء أسلوب أو عملية ثنائي مثل x < y.

يمكنك تحويل و تشغيل التعليمات البرمجية الممثلة بأشجار التعبير. وهذا يمكّنه التعديل ديناميكياً على التعليمات البرمجية القابلة للتنفيذ, تنفيذ استعلامات LINQ في القواعد المتنوعة و إنشاء الاستعلامات الديناميكية. للحصول على معلومات أكثر حول أشجار التعبير في LINQ, راجع كيفية القيام بما يلي: استخدام أشجار التعبير لإنشاء الاستعلامات الديناميكيةو Walkthrough: Creating an IQueryable LINQ Provider.

يتم إستخدام أشجار التعبير أيضاً في وقت تشغيل اللغة حيوية (DLR) لتوفير إمكانية التشغيل التفاعلي بين لغات ديناميكي .NET Framework و لتمكين كتّاب المحول البرمجي لإرسال أشجار تعبير بدلاً من Microsoft Intermediate Language (MSIL). لمزيد من المعلومات حول DLR راجع نظرة عامة حيوية وقت تشغيل اللغة.

يمكنك جعل C# أو برنامج التحويل البرمجي Visual Basic أن يقوم بإنشاء شجرة تعبير لك استناداً إلى تعبير lambda مجهول أو يمكنك إنشاء أشجار التعبير يدوياً بإستخدام مساحة الاسم System.Linq.Expressions.

إنشاء تعبير أشجار من التعبيرات لامدا

عندما يتم وضع تعبير lambda لمتغير من نوع Expression<TDelegate>، يقوم المحول البرمجي emites التعليمات البرمجية من بناء شجرة التعبيرات التي تمثل التعبير lambda.

يمكن ل"C# و compilers Visual Basic" إنشاء أشجار التعبير فقط من تعبير lambdas (أو lambdas ذو خط مفرد). لا يمكنها تحليل عبارة lambdas (أو lambdas متعدد الأخط). للحصول على أكثر راجع المعلومات حول تعبيرات لامدا في C#, التعبيرات لامدا (C# البرمجة الدليل)؛ و لVisual Basic، راجع التعبيرات لامدا.

شرح أمثلة تعليمات برمجية التالي كيفية إنشاء compilers C# و Visual Basic يحتوي شجرة التعبيرات الذي يمثل التعبير lambda num => num < 5(C#) أو Function(num) num < 5(Visual Basic).

Dim lambda As Expression(Of Func(Of Integer, Boolean)) =
    Function(num) num < 5
Expression<Func<int, bool>> lambda = num => num < 5;

إنشاء تعبير أشجار عن طريق إستخدام واجهة برمجة التطبيقات (API)

لإنشاء أشجار التعبير عن طريق إستخدام واجهة برمجة التطبيقات (API) ، إستخدم فئة Expression. تتضمن هذه الفئة أساليب المصنع الثابتة التي تقوم بإنشاء عقد شجرة التعبير لأنواع معينة على سبيل المثال ParameterExpression، والذي يمثل المتغير أو المعلمة, أو MethodCallExpression ، والذي يمثل أسلوب الاتصال. ParameterExpression ،MethodCallExpression ، و أنواع التعبيرات الخاصة الأخرى أيضاً معرفة في مساحة الاسم System.Linq.Expressions . هذه الأنواع مشتقة من الملخص نوع Expression.

يوضح مثال التعليمات البرمجية التالي كيفية إنشاء شجرة التعبير التي تمثل تعبير لامدا num => num < 5 (C#) أو Function(num) num < 5 (Visual Basic) بإستخدام 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})

            // Add the following using directive to your code file:
            // using System.Linq.Expressions;

            // Manually build the expression tree for 
            // the lambda expression num => num < 5.
            ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
            ConstantExpression five = Expression.Constant(5, typeof(int));
            BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
            Expression<Func<int, bool>> lambda1 =
                Expression.Lambda<Func<int, bool>>(
                    numLessThanFive,
                    new ParameterExpression[] { numParam });

في ".NET Framework 4،" تدعم أشجار التعبير API أيضاً التعيينات وتعبيرات تدفق عناصر التحكم مثل حلقات كتل الشرطي وكتل try-catch. بإستخدام واجهة برمجة التطبيقات (API) ، يمكنك إنشاء أشجار التعبير الموجودة أكثر تعقيدًا من تلك التي يمكن إنشاؤها من التعبيرات لامدا بواسطة compilers C# و Visual Basic. يوضح المثال التالي كيفية إنشاء شجرة التعبيرات التي تحسب مضروب رقم.

' 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.
// Creating a parameter expression.
ParameterExpression value = Expression.Parameter(typeof(int), "value");

// Creating an expression to hold a local variable. 
ParameterExpression result = Expression.Parameter(typeof(int), "result");

// Creating a label to jump to from a loop.
LabelTarget label = Expression.Label(typeof(int));

// Creating a method body.
BlockExpression block = Expression.Block(
    // Adding a local variable.
    new[] { result },
    // Assigning a constant to a local variable: result = 1
    Expression.Assign(result, Expression.Constant(1)),
    // Adding a loop.
        Expression.Loop(
    // Adding a conditional block into the loop.
           Expression.IfThenElse(
    // Condition: value > 1
               Expression.GreaterThan(value, Expression.Constant(1)),
    // If true: result *= value --
               Expression.MultiplyAssign(result,
                   Expression.PostDecrementAssign(value)),
    // If false, exit the loop and go to the label.
               Expression.Break(label, result)
           ),
    // Label to jump to.
       label
    )
);

// Compile and execute an expression tree.
int factorial = Expression.Lambda<Func<int, int>>(block, value).Compile()(5);

Console.WriteLine(factorial);
// Prints 120.

لمزيد من المعلومات، راجع إنشاء الأساليب الديناميكية في 2010 Visual Studio.

تحليل أشجار التعبير

يوضح مثال التعليمات البرمجية التالي كيفية تمثيل شجرة التعبير لتعبير لامدا num => num < 5 (C#) أو Function(num) num < 5 (Visual Basic) يمكن أن تتحلل إلى أجزاءه.


        ' 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


// Add the following using directive to your code file:
// using System.Linq.Expressions;

// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;

// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;

Console.WriteLine("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            

immutability لأشجار التعبير

يجب أن تكون أشجار التعبير immutable. وهذا يعني أنه إذا كنت تريد تعديل شجرة التعبيرات, يجب تكوين شجرة تعبيرات جديدة بواسطة نسخ الموجودة و استبدال العقد الموجودة فيها. يمكنك إستخدام زائر شجرة التعبير لاجتياز شجرة التعبيرات الموجودة. لمزيد من المعلومات، راجع كيفية القيام بما يلي: تعديل تعبير أشجار (C# و Visual Basic).

ترجمة أشجار التعبير

يوفر النوع Expression<TDelegate> أسلوب Compile الذي يترجم الرمز الممثل بشجرة التعبيرات لتفويض قابل للتنفيذ.

مثال التعليمات البرمجية التالي يوضح كيفية ترجمة شجرة التعبير و تشغيل التعليمات البرمجية الناتجة.

' 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.
// Creating an expression tree.
Expression<Func<int, bool>> expr = num => num < 5;

// Compiling the expression tree into a delegate.
Func<int, bool> result = 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.

لمزيد من المعلومات، راجع كيفية القيام بما يلي: تنفيذ شجرة التعبيرات (C# و Visual Basic).

راجع أيضًا:

المهام

كيفية القيام بما يلي: تنفيذ شجرة التعبيرات (C# و Visual Basic)

كيفية القيام بما يلي: تعديل تعبير أشجار (C# و Visual Basic)

المرجع

التعبيرات لامدا (C# البرمجة الدليل)

System.Linq.Expressions

المبادئ

نظرة عامة حيوية وقت تشغيل اللغة

التعبيرات لامدا

موارد أخرى

أساسيات شجرة التعبيرات

إنشاء الأساليب الحيوية مع أشجار التعبير في ‏‫Visual Studio 2010

مفاهيم البرمجة