الأصناف العامة (Generics) والكتابة في C#: كتابة كود مرن دون تكرار

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

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

ابدأ الدورة

الأصناف العامة (Generics) والكتابة في C#: لماذا لا يمكن الاستغناء عنها؟



تخيل أنك تبني منزلًا، لكن في كل مرة تحتاج فيها إلى دق مسمار، تقوم بنحت مطرقة جديدة خصيصًا لهذا المسمار. سخيف، أليس كذلك؟ هذا هو شكل الكود بدون الأصناف العامة (Generics). في C#، الأصناف العامة (Generics) هي تلك المطرقة العالمية التي تناسب أي مهمة، لكنها لا تفقد دقتها.



اليوم سنشرح كيف الأصناف العامة (Generics) والكتابة في C# تحول كودك من مجموعة من الحلول المؤقتة المتناثرة إلى نظام منظم ومرن وآمن. ستتعلم كيفية كتابة طرق وفئات عامة تعمل مع أي نوع بيانات، لكن دون التضحية بالأداء. هيا بنا!



ما هي الأصناف العامة (Generics) ولماذا نحتاجها؟



الأصناف العامة (Generics) هي آلية تسمح بإنشاء فئات وطرق وواجهات تعمل مع أي نوع بيانات، مع الحفاظ على الكتابة الصارمة في مرحلة التجميع. يبدو الأمر معقدًا؟ في الواقع، الأمر بسيط.



قبل ظهور الأصناف العامة (Generics) في C# (الإصدار 2.0، عام 2005)، كان المطورون يستخدمون طريقتين:

  • التكرار (كوبي بيست) — إنشاء فئة منفصلة لكل نوع (int, string, double، إلخ).
  • object — استخدام النوع الأساسي object، مما يؤدي إلى التغليف/فك التغليف (boxing/unboxing) وفقدان الأداء.


كلا الخيارين سيئان. الأول يضيع الوقت، والثاني يضيع الأداء. الأصناف العامة (Generics) تحل المشكلتين معًا.



كيف تبدو الأصناف العامة (Generics) عمليًا؟



// بدون Generics: تكرار لكل نوعpublic class IntList{    private int[] items = new int[10];    public void Add(int item) { /* ... */ }}

public class StringList{ private string[] items = new string[10]; public void Add(string item) { /* ... */ }}

// مع Generics: فئة واحدة لجميع الحالاتpublic class GenericList<T>{ private T[] items = new T[10]; public void Add(T item) { /* ... */ }}

// الاستخدامvar intList = new GenericList<int>();var stringList = new GenericList<string>();


لاحظ: GenericList<T> هو قالب. بدلاً من T، يمكنك وضع أي نوع (int, string, فئة خاصة بك)، ويقوم المترجم بإنشاء نسخة محددة من الكود لهذا النوع. لا تكرار، ولا object.



الكتابة في C#: ثابتة، صارمة، آمنة



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



عندما تكتب List<int>، يعرف المترجم بالضبط أن داخل القائمة توجد أعداد صحيحة فقط. إذا حاولت إضافة سلسلة نصية، ستحصل على خطأ في التجميع، وليس استثناءً في وقت التشغيل. هذا هو أمان الأنواع.



Generics مقابل object: معركة الأداء



// مثال سيء باستخدام objectArrayList badList = new ArrayList();badList.Add(123);           // تغليف int -> objectint value = (int)badList[0]; // فك تغليف object -> int

// مثال جيد باستخدام GenericsList<int> goodList = new List<int>();goodList.Add(123); // بدون تغليفint value = goodList[0]; // بدون فك تغليف


بالنسبة للأنواع القيمية (int, double, struct)، يمكن أن يصل الفرق في الأداء إلى 10-20 مرة. بالنسبة للأنواع المرجعية (class)، لا يوجد تغليف، لكن الأصناف العامة (Generics) لا تزال تتفوق بسبب عدم الحاجة إلى تحويلات الأنواع.



الطرق العامة: مرونة بدون كود زائد



الأصناف العامة (Generics) لا تعمل فقط مع الفئات، بل مع الطرق أيضًا. لنفترض أنك بحاجة إلى كتابة طريقة لتبديل عنصرين. بدون Generics، سيكون عليك كتابة العديد من التحميلات الزائدة:



// بدون Genericspublic void SwapInt(ref int a, ref int b) { int temp = a; a = b; b = temp; }public void SwapString(ref string a, ref string b) { string temp

المدونات

توصيات الكتب