تخطَّ إلى المحتوى

#️⃣ شرح C#

الهياكل والتعدادات (Struct و Enum)

الدرس 25 من 30· ⏱ 3 دقائق قراءة· 🗓 آخر تحديث: ١٦ أكتوبر ٢٠٢٦

struct — نوع قيمي مخصّص

struct يشبه class في الصياغة لكنه نوع قيمي: يُنسخ عند التمرير أو الإسناد بدل مشاركة نفس المرجع.

struct Point
{
    public int X;
    public int Y;

    public Point(int x, int y) { X = x; Y = y; }
}

Point p1 = new Point(1, 2);
Point p2 = p1;      // نسخة كاملة، ليست نفس البيانات
p2.X = 99;

Console.WriteLine(p1.X);   // 1 — لم يتأثّر
Console.WriteLine(p2.X);   // 99

متى تستخدم struct بدل class؟

structclass
النوعقيمي (نسخ)مرجعي (مشاركة)
الحجم المناسبصغير (بضع خانات)متوسط إلى كبير
الوراثةلا تدعمهاتدعمها
مثال جاهزint, double, DateTime, Pointمعظم أصنافك الخاصة

💡 استخدم struct لبيانات صغيرة غير قابلة للتغيير غالبًا (إحداثية، لون، مبلغ)، وclass لكل ما عداه.

لماذا "صغيرة"؟ لأن كل إسناد وكل تمرير لدالة ينسخ الـ struct كاملًا. نسخ إحداثية من رقمين أرخص من تتبّع مرجع في الذاكرة، أما struct بعشرات الحقول يُمرَّر في حلقة فيُنسخ آلاف المرات، وهنا يصبح تمرير مرجع class واحد أسرع.

new Point() بدون وسائط متاح لأي struct حتى لو لم تكتب مُنشئًا بلا وسائط، ويعطيك نسخة كل حقولها بقيمها الافتراضية (0، false، null).

enum — مجموعة قيم ثابتة

يمنع الأرقام السحرية ويجعل الكود مقروءًا:

enum Season
{
    Spring,   // 0
    Summer,   // 1
    Autumn,   // 2
    Winter    // 3
}

Season current = Season.Autumn;

النوع الأساسي الافتراضي int والقيم تبدأ من 0. يمكن تخصيصه وإعطاء قيم صريحة:

enum HttpStatus : ushort
{
    OK = 200,
    NotFound = 404,
    ServerError = 500
}

enum مع switch

string Describe(Season s) => s switch
{
    Season.Spring => "ربيع",
    Season.Summer => "صيف",
    Season.Autumn => "خريف",
    Season.Winter => "شتاء",
    _ => "غير معروف"
};

التحويل بين enum و int

int code = (int)HttpStatus.NotFound;        // 404
HttpStatus s = (HttpStatus)200;              // HttpStatus.OK
bool valid = Enum.IsDefined(typeof(HttpStatus), 999);   // false

⚠️ التحويل (HttpStatus)999 لا يفشل: يعطيك قيمة enum غير معرَّفة بصمت، لأن الـ enum في النهاية رقم. لذلك تحقّق بـ Enum.IsDefined من أي رقم قادم من مصدر خارجي (قاعدة بيانات، طلب API) قبل الاعتماد عليه.

ومن النص إلى enum، استخدم Enum.TryParse بدل Enum.Parse حين قد يكون النص غير صالح:

if (Enum.TryParse("NotFound", out HttpStatus parsed))
    Console.WriteLine((int)parsed);   // 404

bit flags — دمج عدّة قيم

عندما يمثّل التعداد تركيبة اختيارات لا اختيارًا واحدًا، استخدم قوى 2 مع [Flags]:

[Flags]
enum FilePermission
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4
}

var p = FilePermission.Read | FilePermission.Write;
Console.WriteLine(p);                          // Read, Write
Console.WriteLine(p.HasFlag(FilePermission.Write));   // True

🎯 التالي: المطابقة النمطية (Pattern Matching).

شرح الهياكل والتعدادات (Struct و Enum) — C# بالعربي
الهياكل والتعدادات (Struct و Enum) — C# بالعربي · The Code Fix

📚 لمزيد من التعمّق في C#، راجِع توثيق C# من Microsoft.

هل كان هذا الدرس مفيدًا؟