ترجمة التعبيرات وتنفيذها
حوّلوا أشجار التعبيرات إلى delegates قابلة للتشغيل
ترجمة التعبيرات وتنفيذها درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
من الشجرة إلى Delegate
تظل شجرة التعبيرات بيانات إلى أن تقوموا بتجميعها. يحوّل Expression<TDelegate>.Compile() الشجرة إلى delegate حقيقي يمكنكم استدعاؤه.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
Func<int, int> fn = tree.Compile();
Console.WriteLine(fn(5)); // 6تجميع شجرة منشأة يدويًا
تُجمَّع الأشجار التي تنشئونها يدويًا بالطريقة نفسها، فتنتج delegate عمليًا.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Multiply(x, Expression.Constant(3));
var lambda = Expression.Lambda<Func<int, int>>(body, x);
var fn = lambda.Compile();
Console.WriteLine(fn(4)); // 12استدعاء النتيجة
يتصرف delegate المُجمَّع مثل أي delegate آخر: يمكنكم استدعاؤه وتخزينه وتمريره.
using System;
using System.Linq.Expressions;
Expression<Func<int, int, int>> addExpr = (a, b) => a + b;
var add = addExpr.Compile();
Console.WriteLine(add(2, 3)); // 5
Console.WriteLine(add(10, 20)); // 30التجميع ليس مجانيًا
ينطوي التجميع على تكلفة أثناء التشغيل، لذا خزّنوا delegate الناتج وأعيدوا استخدامه بدلًا من تجميعه عند كل استدعاء.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x * x;
var square = tree.Compile(); // compile once
for (int i = 1; i <= 3; i++)
Console.Write(square(i) + " "); // 1 4 9
Console.WriteLine();إنشاء predicates ديناميكيًا
من الاستخدامات الشائعة إنشاء predicates للتصفية أثناء التشغيل من إدخال المستخدم، ثم تجميعها إلى Func.
using System;
using System.Linq.Expressions;
var n = Expression.Parameter(typeof(int), "n");
var isPositive = Expression.GreaterThan(n, Expression.Constant(0));
var pred = Expression.Lambda<Func<int, bool>>(isPositive, n).Compile();
Console.WriteLine(pred(5)); // True
Console.WriteLine(pred(-2)); // Falseدمج الشروط
استخدموا Expression.AndAlso / OrElse لدمج predicates قبل تجميعها.
using System;
using System.Linq.Expressions;
var n = Expression.Parameter(typeof(int), "n");
var inRange = Expression.AndAlso(
Expression.GreaterThanOrEqual(n, Expression.Constant(1)),
Expression.LessThanOrEqual(n, Expression.Constant(10)));
var fn = Expression.Lambda<Func<int, bool>>(inRange, n).Compile();
Console.WriteLine(fn(5) + " " + fn(11)); // True Falseتجميع الحسابات
يمكنكم تركيب صيغ حسابية أثناء التشغيل، وهو أمر مفيد لمحركات القواعد والآلات الحاسبة.
using System;
using System.Linq.Expressions;
var p = Expression.Parameter(typeof(double), "p");
// price * 1.2 (add 20% tax)
var withTax = Expression.Multiply(p, Expression.Constant(1.2));
var calc = Expression.Lambda<Func<double, double>>(withTax, p).Compile();
Console.WriteLine(calc(100)); // 120استخدام DynamicInvoke مع lambdas غير المحددة النوع
إذا استخدمتم Expression.Lambda غير العامة، فجمّعوها إلى Delegate واستدعوا DynamicInvoke.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Add(x, Expression.Constant(10));
Delegate d = Expression.Lambda(body, x).Compile();
Console.WriteLine(d.DynamicInvoke(5)); // 15ملاحظة حول الأداء
يعمل التعبير المُجمَّع بسرعة تقارب سرعة delegate بعد التجميع لمرة واحدة. أما في المسارات الساخنة، فجمّعوه مرة واحدة عند بدء التشغيل وخزّنوا delegate.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + x;
var doubler = tree.Compile();
int total = 0;
for (int i = 0; i < 5; i++) total += doubler(i);
Console.WriteLine(total); // 0+2+4+6+8 = 20تظهر الأخطاء أثناء التجميع
إذا كانت الشجرة غير صحيحة، كأن تفتقد معلمة مثلًا، فإن Compile() يرمي استثناءً؛ لذا تحقّقوا من الأشجار قبل الاعتماد عليها.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var y = Expression.Parameter(typeof(int), "y");
try {
// body references y but lambda only declares x
var lambda = Expression.Lambda<Func<int, int>>(Expression.Add(x, y), x);
lambda.Compile();
} catch (InvalidOperationException) {
Console.WriteLine("unbound parameter");
}تجميع المفاهيم
أنشئوا صيغة صغيرة وجمّعوها وشغّلوها ضمن مسار واحد.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var formula = Expression.Add(
Expression.Multiply(x, Expression.Constant(2)),
Expression.Constant(3)); // 2x + 3
var fn = Expression.Lambda<Func<int, int>>(formula, x).Compile();
Console.WriteLine(fn(4)); // 11اختبار سريع
تأكدوا من كيفية تنفيذ شجرة تعبيرات.
مراجعة
تعلّمتم تجميع أشجار التعبيرات وتنفيذها.
- يحوّل
Compile()الشجرة إلى delegate قابل للاستدعاء. - خزّنوا delegate، فالتجميع ينطوي على تكلفة تُدفع مرة واحدة.
- أنشئوا predicates وصيغًا ديناميكيًا، ثم جمّعوها.
- تؤدي الأشجار غير الصحيحة إلى استثناء عند استدعاء
Compile().
الأسئلة الشائعة
هل درس «ترجمة التعبيرات وتنفيذها» مجاني؟
نعم — نص درس «ترجمة التعبيرات وتنفيذها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «ترجمة التعبيرات وتنفيذها»؟
حوّلوا أشجار التعبيرات إلى delegates قابلة للتشغيل تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «ترجمة التعبيرات وتنفيذها»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ما أشجار التعبيرات؟
- إنشاء التعبيرات يدويًا
- ترجمة التعبيرات وتنفيذها
- أشجار التعبيرات في موفّري LINQ