Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الـ Attributes والـ Reflection

جزء من قسم البرمجة كائنية التوجه في رحلة C# على Coddy. الدرس 44 من 70.

السمات هي علامات بيانات وصفية تُرفق بعناصر التعليمات البرمجية مثل class وmethods أو الخصائص. وهي لا تغيّر طريقة تنفيذ التعليمات البرمجية مباشرةً، لكنها توفر معلومات يمكن قراءتها في وقت التشغيل. الانعكاس هو الآلية التي تقرأ هذه البيانات الوصفية.

تطبّق attribute بوضعها بين قوسين مربعين أعلى العنصر المستهدف:

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Serializable]
public class Person
{
    public string Name { get; set; }
}

يمكنك إنشاء سمات مخصصة عن طريق الوراثة من Attribute:

public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}

[Author("John")]
public class Calculator { }

تتيح لك الانعكاسية فحص الأنواع وقراءة السمات أثناء التشغيل باستخدام مساحة الأسماء System.Reflection:

Type type = typeof(Calculator);
var attr = type.GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(attr.Name);  // John

يمكنك أيضًا اكتشاف methods وخصائص واستدعاؤها ديناميكيًا:

MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
    Console.WriteLine(method.Name);

تُشغّل السمات والانعكاس العديد من أطر العمل — إذ تستخدمها مكتبات التسلسل للتحكم في مخرجات JSON، وتستخدمها أطر الاختبار لاكتشاف methods الاختبار، كما تستخدمها حاويات حقن الاعتماديات لربط الخدمات تلقائيًا.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لاكتشاف المكونات الإضافية يستخدم السمات المخصصة وميزة الانعكاس للعثور تلقائيًا على الفئات الموسومة كمكونات إضافية ووصفها. يشبه هذا الطريقة التي تكتشف بها أُطر العمل الحقيقية المكونات أو أساليب الاختبار أو نقاط نهاية API في وقت التشغيل.

ستنظّم التعليمات البرمجية عبر ثلاثة ملفات:

  • PluginAttribute.cs: أنشئ سمة مخصصة تُسمى PluginAttribute في مساحة الأسماء PluginSystem. يجب أن تقوم سمتك بما يلي:
    • ترث من Attribute
    • تحتوي على خاصيتين للقراءة فقط: Name (سلسلة نصية) وVersion (سلسلة نصية)
    • تقبل القيمتين كلتيهما من خلال مُنشئها
  • Plugins.cs: أنشئ عدة فئات للمكونات الإضافية في مساحة الأسماء PluginSystem. يجب تزيين بعضها باستخدام PluginAttribute، وألا تُزيَّن إحداها:
    • ImageProcessor - موسومة باستخدام [Plugin("Image Processor", "1.0")]
    • DataExporter - موسومة باستخدام [Plugin("Data Exporter", "2.5")]
    • HelperUtility - غير موسومة بأي سمة (هذه مجرد فئة عادية)
    يمكن أن تكون كل فئة فارغة - فنحن مهتمون فقط باكتشاف بياناتها الوصفية من خلال الانعكاس.
  • Program.cs: في ملفك الرئيسي، استخدم الانعكاس لاكتشاف جميع الفئات التي تحتوي على PluginAttribute. اطبع معلومات كل مكوّن إضافي يتم اكتشافه. ستحتاج إلى:
    • الحصول على جميع الأنواع من assembly الحالية
    • فحص كل نوع بحثًا عن PluginAttribute
    • استخراج الخاصيتين Name وVersion للسمات وعرضهما

استخدم System.Reflection لفحص الأنواع واسترداد السمات المخصصة. تُرجع الطريقة GetCustomAttribute<T>() القيمة null إذا لم تكن السمة موجودة، لذا يمكنك استخدام ذلك لتصفية الفئات التي تمثل مكونات إضافية فعلية.

اطبع كل مكوّن إضافي يتم اكتشافه بهذا التنسيق، واحدًا في كل سطر:

Plugin: {Name} (v{Version})

يجب طباعة المكونات الإضافية بالترتيب التالي: ImageProcessor أولًا، ثم DataExporter. يجب ألا تظهر الفئة HelperUtility في الناتج لأنها تفتقر إلى السمة.

الناتج المتوقع:

Plugin: Image Processor (v1.0)
Plugin: Data Exporter (v2.5)

يوضح هذا التحدي كيف تستخدم أُطر العمل السمات كعلامات، وتستخدم الانعكاس لاكتشافها - وتدعم التقنية نفسها حاويات حقن التبعية ومكتبات التسلسل وأُطر عمل الاختبار!

جرّب بنفسك

using System;
using System.Reflection;
using PluginSystem;

class Program
{
    public static void Main(string[] args)
    {
        // TODO: احصل على جميع الأنواع من التجميع الحالي
        // تلميح: استخدم Assembly.GetExecutingAssembly().GetTypes()
        
        // TODO: كرر عبر كل نوع وتحقق مما إذا كان يحتوي على PluginAttribute
        // تلميح: استخدم type.GetCustomAttribute<PluginAttribute>()
        
        // TODO: إذا كانت السمة موجودة، اطبع معلومات الإضافة بالتنسيق:
        // Plugin: {Name} (v{Version})
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C# عبر الإنترنت