الـ Generics (الأصناف والدوال)
جزء من قسم البرمجة كائنية التوجه في رحلة C# على Coddy. الدرس 42 من 70.
تتيح لك الأنواع العامة كتابة أصناف وطرائق تعمل مع أي نوع بيانات مع الحفاظ على أمان الأنواع. بدلًا من كتابة أصناف منفصلة لـ IntList وStringList وDoubleList، تكتب صنفًا عامًا واحدًا يتعامل معها جميعًا.
يستخدم الصنف العام معامل نوع، يُسمى عادةً T، ويُحاط بأقواس زاوية:
public class Box<T>
{
private T content;
public void Store(T item) => content = item;
public T Retrieve() => content;
}
// الاستخدام مع أنواع مختلفة
Box<int> intBox = new Box<int>();
intBox.Store(42);
Box<string> stringBox = new Box<string>();
stringBox.Store("Hello");عندما تنشئ Box<int>، يستبدل المترجم كل T بـ int. يوفّر هذا التحقق من الأنواع في وقت الترجمة، فلا يمكنك تخزين سلسلة نصية في صندوق int عن طريق الخطأ.
تعمل الأساليب العامة بطريقة مشابهة، إذ تسمح لأسلوب واحد بالعمل مع أنواع مختلفة:
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
int x = 1, y = 2;
Swap(ref x, ref y); // x=2, y=1يستنتج المترجم النوع من الوسائط، لذا لا تحتاج إلى كتابة Swap<int> صراحةً. تُعد الأنواع العامة أساس المجموعات مثل List<T> وDictionary<TKey, TValue>، إذ تتيح كتابة شيفرة قابلة لإعادة الاستخدام وآمنة الأنواع.
التحدي
سهللنبنِ نظامًا عامًا Storage<T> يمكنه الاحتفاظ بعناصر من أي نوع وإدارتها. ستنشئ فئة حاوية قابلة لإعادة الاستخدام توضّح قوة الأنواع العامة — اكتبها مرة واحدة واستخدمها مع الأعداد الصحيحة أو السلاسل النصية أو أي نوع آخر!
ستنظّم شيفرتك عبر ملفين:
Storage.cs: أنشئ فئة عامةStorage<T>في مساحة الأسماءDataStorage. ينبغي أن تحتوي حاوية التخزين على:- مصفوفة خاصة من النوع
Tللاحتفاظ بالعناصر، وخاصيةCountلتتبّع عدد العناصر المخزّنة - مُنشئًا يقبل السعة لتهيئة المصفوفة الداخلية
- طريقة
Add(T item)تضيف عنصرًا إذا توفرت مساحة - طريقة
Get(int index)تُعيد العنصر عند الفهرس المحدد - طريقة
GetAll()تُعيد جميع العناصر المخزّنة، مع الفصل بينها باستخدام", "
- مصفوفة خاصة من النوع
Program.cs: في ملفك الرئيسي، اعرض عمل فئتك العامة مع نوعين مختلفين. أنشئStorage<int>وStorage<string>، وأضف عناصر إلى كل منهما، وأظهر أن الفئة نفسها تعمل بسلاسة مع كلا النوعين.
ستتلقى أربع قيم إدخال:
- العدد الصحيح الأول المراد تخزينه
- العدد الصحيح الثاني المراد تخزينه
- السلسلة النصية الأولى المراد تخزينها
- السلسلة النصية الثانية المراد تخزينها
أنشئ مخزنًا للأعداد الصحيحة بسعة 5 ومخزنًا للسلاسل النصية بسعة 5. أضف العددين الصحيحين إلى مخزن الأعداد الصحيحة، والسلسلتين النصيتين إلى مخزن السلاسل النصية.
اطبع المخرجات بهذا التنسيق:
Int storage: {GetAll()}
Int count: {Count}
First int: {Get(0)}
String storage: {GetAll()}
String count: {Count}
First string: {Get(0)}على سبيل المثال، إذا كانت قيم الإدخال هي 42 و100 وHello وWorld، فينبغي أن تكون المخرجات:
Int storage: 42, 100
Int count: 2
First int: 42
String storage: Hello, World
String count: 2
First string: Helloلاحظ أنك تكتب فئة Storage<T> مرة واحدة، لكنها تعمل على نحو مثالي مع كل من int وstring — هذا هو سحر الأنواع العامة! يضمن المصرّف سلامة الأنواع، لذا لا يمكنك إضافة سلسلة نصية إلى مخزن الأعداد الصحيحة عن طريق الخطأ.
جرّب بنفسك
using System;
using DataStorage;
class Program
{
public static void Main(string[] args)
{
// اقرأ المدخلات
int num1 = Convert.ToInt32(Console.ReadLine());
int num2 = Convert.ToInt32(Console.ReadLine());
string str1 = Console.ReadLine();
string str2 = Console.ReadLine();
// TODO: أنشئ Storage<int> بسعة 5
// TODO: أضف العددين الصحيحين إلى مخزن الأعداد الصحيحة
// TODO: أنشئ Storage<string> بسعة 5
// TODO: أضف السلسلتين النصيتين إلى مخزن السلاسل النصية
// TODO: اطبع المخرجات بالتنسيق المطلوب
// Int storage: {GetAll()}
// عدد عناصر Int: {Count}
// أول int: {Get(0)}
// String storage: {GetAll()}
// String count: {Count}
// First string: {Get(0)}
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injectionتدرّب بنفسك: مترجم C# عبر الإنترنت