كيفية الحصول على قيمة خاصية بالاسم عبر الانعكاس في C#: دليل كامل

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

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

ابدأ الدورة

كيفية الحصول على قيمة خاصية بالاسم عبر الانعكاس في C#: شرح للمبتدئين

\n\n

تخيل موقفًا: أنت تكتب كودًا تحتاج فيه إلى الوصول ديناميكيًا، بشكل فوري، إلى خاصية كائن. اسم هذه الخاصية يأتي، على سبيل المثال، من ملف إعدادات، أو من طلب JSON، أو يتم إدخاله بواسطة المستخدم. لا يمكنك كتابة object.PropertyName بشكل ثابت - لأنك لا تعرف الاسم مسبقًا. ما الحل؟

\n\n

هنا يأتي دور الانعكاس (reflection) - وهي آلية قوية في C# تسمح بفحص أنواع البيانات وأعضائها (الخصائص، الدوال، الحقول) أثناء تنفيذ البرنامج. في هذه المقالة، سنشرح السؤال الأكثر شيوعًا على Stack Overflow: كيفية الحصول على قيمة خاصية كائن من سلسلة نصية تحتوي على اسمها. سنشرح ذلك بأمثلة حقيقية، من البسيط إلى المعقد، وسنناقش الأخطاء الشائعة التي يقع فيها المبتدئون.

\n\n

ما هو الانعكاس ولماذا نحتاجه؟

\n\n

الانعكاس في C# هو قدرة البرنامج على "النظر إلى نفسه" والحصول على معلومات حول أنواعه الخاصة. توفر مساحة الأسماء System.Reflection فئات مثل Type و PropertyInfo و MethodInfo، والتي تسمح لك بما يلي:

\n\n
    \n
  • معرفة جميع الخصائص والدوال في الفئة.
  • \n
  • إنشاء نسخ من الفئات بدون استخدام العامل new.
  • \n
  • استدعاء الدوال والحصول على/تعيين قيم الخصائص باستخدام أسمائها النصية.
  • \n
\n\n

بدون الانعكاس، لن تتمكن، على سبيل المثال، من كتابة مابر كائنات عام (مثل AutoMapper) أو مسلسل (Serializer) يعمل مع أي نوع بيانات.

\n\n

مثال أساسي: الحصول على قيمة خاصية بالاسم

\n\n

لنفترض أن لدينا فئة بسيطة Person:

\n\n
public class Person\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n    public string City { get; set; }\n}
\n\n

نريد كتابة دالة تأخذ كائنًا من نوع Person وسلسلة نصية باسم الخاصية (مثل "Name" أو "Age") وتعيد قيمة تلك الخاصية. إليك كيفية القيام بذلك باستخدام الانعكاس:

\n\n
using System;\nusing System.Reflection;\n\npublic static object GetPropertyValue(object obj, string propertyName)\n{\n    if (obj == null) throw new ArgumentNullException(nameof(obj));\n    if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("اسم الخاصية لا يمكن أن يكون فارغًا", nameof(propertyName));\n\n    // الحصول على نوع الكائن\n    Type type = obj.GetType();\n\n    // الحصول على معلومات الخاصية باسمها\n    PropertyInfo propertyInfo = type.GetProperty(propertyName);\n\n    // التحقق من وجود الخاصية\n    if (propertyInfo == null)\n        throw new ArgumentException($"الخاصية '{propertyName}' غير موجودة في النوع '{type.Name}'");\n\n    // الحصول على قيمة الخاصية\n    return propertyInfo.GetValue(obj);\n}
\n\n

الآن نستخدم الدالة:

\n\n
var person = new Person { Name = "آنا", Age = 30, City = "موسكو" };\n\nstring name = (string)GetPropertyValue(person, "Name");\nint age = (int)GetPropertyValue(person, "Age");\n\nConsole.WriteLine($"الاسم: {name}, العمر: {age}"); // الإخراج: الاسم: آنا, العمر: 30
\n\n

كل شيء يعمل! النقاط الرئيسية:

\n
    \n
  • obj.GetType() - يحصل على كائن Type الذي يصف نوع الكائن الخاص بنا.
  • \n
  • type.GetProperty("Name") - يبحث عن خاصية عامة بالاسم "Name". يُرجع PropertyInfo أو null إذا لم يتم العثور على الخاصية.
  • \n
  • propertyInfo.GetValue(obj) - يُرجع قيمة هذه الخاصية للنسخة المحددة obj.
  • \n
\n\n

ملاحظات هامة وأخطاء شائعة (ما لا يخبرك به المبتدئون)

\n\n

1. حساسية حالة الأحرف

\n

الدالة GetProperty بشكل افتراضي حساسة لحالة الأحرف. إذا حددت "name" بدلاً من "Name"، فلن يتم العثور على الخاصية

المدونات

توصيات الكتب