البرمجة الوظيفية في C#: المبادئ والأمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

البرمجة الوظيفية في لغة C#: من النظرية إلى التطبيق

البرمجة الوظيفية (FP) هي نموذج يتم فيه التعامل مع العمليات الحسابية كتقييم للدوال الرياضية، مع تجنب تغيير الحالة والبيانات القابلة للتغيير. على الرغم من أن لغة C# كانت في الأصل لغة موجهة للكائنات، إلا أنها منذ الإصدار 3.0 بدأت في دمج الميزات الوظيفية بنشاط. اليوم، تدعم C# مفاهيم مثل تعبيرات لامدا، LINQ، الأنواع غير القابلة للتغيير، وحتى مطابقة الأنماط. في هذه المقالة، سنقوم بتفصيل المبادئ الأساسية للبرمجة الوظيفية ونوضح كيفية تطبيقها في مشاريع C# الواقعية.



1. الدوال النقية وغياب الآثار الجانبية

الدالة النقية هي دالة:

  • تعيد دائمًا نفس النتيجة لنفس الوسائط (الشفافية المرجعية).
  • ليس لها آثار جانبية (لا تعدل الحالة العامة، أو تكتب في الملفات، أو ترسل طلبات HTTP).

في لغة C#، قد تبدو الدالة النقية كما يلي:

public static int Add(int a, int b) => a + b;

إليك مثال على دالة غير نقية:

public static int AddAndLog(int a, int b){    Console.WriteLine($"Adding {a} and {b}"); // تأثير جانبي    return a + b;}

مزايا الدوال النقية: يسهل اختبارها وتصحيح أخطائها وتنفيذها بالتوازي.



2. عدم القابلية للتغيير

في البرمجة الوظيفية، البيانات غير قابلة للتغيير افتراضيًا. في C#، يتم تحقيق ذلك باستخدام:

  • الكلمة المفتاحية readonly للحقول.
  • هياكل record (C# 9+) التي تنشئ تلقائيًا كائنات غير قابلة للتغيير.
  • المجموعات من مساحة الأسماء System.Collections.Immutable.

مثال مع record:

public record Person(string Name, int Age);

إذا كنت بحاجة إلى تغيير العمر، يتم إنشاء مثيل جديد:

Person person = new("Ivan", 30);Person olderPerson = person with { Age = 31 };

عدم القابلية للتغيير يمنع التعديلات العرضية ويبسط تعدد المهام.



3. الدوال عالية المستوى وتعبيرات لامدا

الدوال عالية المستوى تأخذ دوال أخرى كوسائط أو تعيدها. في C#، يتم تنفيذ ذلك من خلال المفوضين: Func<>، Action<>، Predicate<>.

مثال بسيط هو طريقة Where من LINQ:

List<int> numbers = new() { 1, 2, 3, 4, 5 };var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

هنا، n => n % 2 == 0 هو تعبير لامدا (دالة مجهولة).

يمكنك كتابة دالة عالية المستوى خاصة بك:

public static List<T> Filter<T>(List<T> list, Func<T, bool> predicate){    var result = new List<T>();    foreach (var item in list)        if (predicate(item)) result.Add(item);    return result;}


4. LINQ: أداة قوية بأسلوب وظيفي

LINQ (استعلام متكامل مع اللغة) هو ربما المثال الأبرز للبرمجة الوظيفية في C#. يسمح لك بمعالجة المجموعات بشكل تصريحي، مشابه لـ SQL.

مثال: الحصول على أسماء المستخدمين الأكبر من 18 عامًا، مرتبة حسب العمر:

var users = new List<User>{    new("Anna", 22),    new("Boris", 17),    new("Victor", 30)};

var result = users .Where(u => u.Age >= 18) .OrderBy(u => u.Age) .Select(u => u.Name) .ToList();

يدعم LINQ التقييم البطيء، مما يوفر الموارد.



5. المونادات ونوع Maybe في C#

المونادات هي تجريد لسلسلة العمليات الحسابية مع سياق (مثل التعامل مع القيمة الفارغة أو التزامن). لا تحتوي C# على موناد Maybe مدمج، ولكن من السهل تنفيذه:

public class Maybe<T>{    private readonly T _value;    public bool HasValue { get; }        p                

المدونات

توصيات الكتب