ما الذي يخفيه السمة [Flags] في C#؟
\n\nإذا كنت قد كتبت يومًا ما بلغة C# ورأيت في كود شخص آخر سمة غريبة [Flags] قبل enum، فمن المحتمل أنك تساءلت: "ماذا لو لم أضعها - هل سيتوقف الكود عن العمل؟"
إفساد المفاجأة: لن يتوقف عن العمل. لكن كودك سيصبح مثل دراجة بعجلات مربعة. اليوم سنشرح ماذا تعني سمة [Flags] في C#، وكيفية استخدامها بشكل صحيح في عام 2025، ولماذا بدونها تكون enum الخاصة بك مجرد أرقام، وليست مجموعات ذات معنى.
الموضوع مأخوذ من سؤال حقيقي على Stack Overflow حصد آلاف المشاهدات. وهذا ليس من قبيل الصدفة: الاستخدام الصحيح للأعلام الثنائية هو أحد المهارات التي تميز المطور الذي يفهم أعماق اللغة عن ذلك الذي يكتفي بـ "النسخ واللصق من MSDN".
\n\nما هو [Flags] في C# في الواقع؟
\n\nالسمة [Flags] ليست مفتاحًا سحريًا يغير سلوك المترجم. إنها علامة للمطور وللأدوات (مثل مصحح أخطاء Visual Studio أو الإخراج الطرفي).
عندما تكتب:
\n\n[Flags]\npublic enum FilePermissions\n{\n None = 0,\n Read = 1,\n Write = 2,\n Execute = 4,\n Delete = 8\n}\n\nأنت تقول: "مرحبًا، هذا التعداد ليس لاختيار خيار واحد، بل لمجموعة من عدة خيارات". بدون السمة [Flags]، لا يعرف C# أنك ستقوم بعمليات ثنائية. لكن من الناحية الفنية - يمكنك.
كيف يعمل السحر الثنائي
\n\nالقيم 1, 2, 4, 8 لم تُختر عشوائيًا. في النظام الثنائي، هي:
- \n
1= 0001 \n 2= 0010 \n 4= 0100 \n 8= 1000 \n
كل علم يشغل بتًا خاصًا به. لذلك يمكنك دمج Read و Write كـ 1 | 2 = 3 (0011). وسيفهم النظام: "أوه، تم تفعيل كلا العلمين".
إذا اخترت القيم 1, 2, 3, 4 - فإن الدمج 1 | 2 = 3 سيكون غير قابل للتمييز عن القيمة Execute = 3. لذلك تتطلب الأعلام الثنائية قوى العدد 2.
لماذا نحتاج [Flags] إذا كان يمكننا فقط وضع الأرقام؟
\n\nنعم، من الناحية الفنية يمكنك استخدام العمليات الثنائية بدون السمة. لكن:
\n\n- \n
- قابلية قراءة الكود:
permissions.HasFlag(FilePermissions.Write)أوضح من(permissions & 2) != 0. \n - التصحيح: سيعرض Visual Studio
Read, Writeبدلاً من الرقم3. \n - ToString(): استدعاء
myFlags.ToString()سيعطي "Read, Write" بدلاً من "3". \n - التوثيق الذاتي: أي مطور، عند رؤية
[Flags]، سيفهم القصد فورًا. \n
بدون السمة [Flags] في C#، تفقد كل هذه المزايا. الكود يعمل، لكنه يبدو وكأنه "كتبته في الساعة 2 صباحًا قبل الموعد النهائي".
\n\nأفضل الممارسات للعمل مع [Flags] في عام 2025
\n\n1. استخدم دائمًا قوى العدد 2
\n\nهذه هي القاعدة الأولى. القيم 1, 2, 4, 8, 16, 32... - وليس غير ذلك. للراحة، يمكن استخدام الترميز السداسي عشري:
[Flags]\npublic enum DayOfWeek\n{\n None = 0,\n Monday = 0b_0000_0001, // 1\n Tuesday = 0b_0000_0010, // 2\n Wednesday = 0b_0000_0100, // 4\n Thursday = 0b_0000_1000, // 8\n Friday = 0b_0001_0000, // 16\n Weekend = Monday | Tuesday | Wednesday | Thursday | Friday\n}\n\nلاحظ: قم دائمًا بتضمين None = 0. بدونه، سيكون enum الخاص بك افتراضيًا مساويًا لـ 0، مما قد يعني "لم يتم تحديد شيء".