فحص الأنواع في C#: typeof، GetType أم is؟ تحليل كامل

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

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

ابدأ الدورة

فحص الأنواع في C#: typeof، GetType أم is؟ كيف لا تتوه بين ثلاثة خيارات

\n\n

كل مطور C#، عاجلاً أم آجلاً، يواجه الحاجة للتحقق من نوع كائن. قد يبدو الأمر بسيطاً؟ ولكن عندما يكون أمامك ثلاثة خيارات — typeof، GetType() و is — تتشتت العيون ويتبادر إلى الذهن سؤال منطقي: "أي واحد منهم أختار؟".

\n\n

هذه المقالة ليست مجرد خلاصة جافة من التوثيق. سنحلل كل نهج بأمثلة حقيقية، ونكشف عن المطبات الخفية ونقدم توصيات واضحة. بعد القراءة، ستتوقف عن التخمين وستعرف بالضبط أي أداة تستخدم في موقف معين. هيا بنا!

\n\n

لماذا نحتاج أصلاً إلى فحص الأنواع في C#؟

\n\n

قبل الغوص في التفاصيل، دعنا نتذكر لماذا نحتاج إلى ذلك. C# هي لغة شديدة التحديد (strictly typed)، لكن هذا لا يلغي المواقف التي يكون فيها نوع الكائن معروفاً فقط أثناء التنفيذ. إليك السيناريوهات الأكثر شيوعاً:

\n\n
    \n
  • العمل مع الواجهات والفئات الأساسية: تستلم كائنًا كـ object أو نوع أساسي، وتحتاج إلى معرفة "شخصيته" الحقيقية.
  • \n
  • التسلسل وإلغاء التسلسل: JSON أو XML يأتيان كسلسلة نصية، وتحتاج إلى استعادة النوع المحدد.
  • \n
  • الانعكاس (Reflection): عندما تنشئ كائنات ديناميكياً أو تستدعي دوالاً، مع معرفة اسم النوع فقط.
  • \n
  • تسجيل الأحداث وتصحيح الأخطاء: أحياناً تحتاج فقط إلى إخراج النوع الذي تعمل معه في السجل.
  • \n
\n\n

وهنا يظهر أبطالنا الثلاثة على المسرح. دعنا نتعرف على كل منهم عن قرب.

\n\n

typeof — نظرة ثابتة إلى المستقبل

\n\n

typeof هو عامل (operator) يعيد كائن System.Type لنوع معروف في مرحلة التجميع. يعمل كخدمة استعلام: "قل لي اسم الفئة، وسأعطيك كل المعلومات عنها".

\n\n

كيف يعمل:

\n
Type stringType = typeof(string);\nConsole.WriteLine(stringType.FullName); // الإخراج: System.String\n\nType intType = typeof(int);\nConsole.WriteLine(intType.FullName); // الإخراج: System.Int32
\n\n

الميزة الأساسية: typeof لا يتطلب نسخة (instance) من الكائن. إنها عملية ثابتة. أنت تقول للمترجم: "لدي نوع MyClass، أعطني بياناته الوصفية".

\n\n

متى تستخدم:

\n
    \n
  • عندما تحتاج إلى النوع باسم الفئة، وليس بناءً على كائن.
  • \n
  • في السمات (attributes) (مثل: [AttributeUsage(typeof(MyAttribute))]).
  • \n
  • في الأنواع العامة (generics): typeof(List<>).
  • \n
\n\n

المطب الخفي: typeof يعيد دائماً النوع الدقيق الذي حددته في الكود. لا يعرف عن الوراثة. إذا كان لديك class Dog : Animal { }، فإن typeof(Animal) لن يصبح أبداً typeof(Dog).

\n\n

GetType() — تحقيق ديناميكي

\n\n

على عكس typeof، يتم استدعاء الدالة GetType() على نسخة الكائن. تأخذ الكائن الحقيقي الموجود في الذاكرة وتقول: "آه، هكذا أنت في الحقيقة!".

\n\n

مثال:

\n
object obj = "مرحباً، أيها العالم!";\nType typeOfObj = obj.GetType();\nConsole.WriteLine(typeOfObj.FullName); // الإخراج: System.String\n\n// والآن الحيلة:\nobject obj2 = 42;\nType typeOfObj2 = obj2.GetType();\nConsole.WriteLine(typeOfObj2.FullName); // الإخراج: System.Int32
\n\n

لاحظ: المتغير obj تم تعريفه كـ object، لكن GetType() "ترى" من خلال هذا الغلاف وتعيد System.String. هذا هو التحديد الديناميكي للنوع.

\n\n

متى تستخدم:

\n
    \n
  • عندما تحتاج إلى معرفة النوع الدقيق للكائن أثناء التنفيذ.
  • \n
  • لمقارنة الأنواع: obj.GetType() == typeof(MyClass).
  • \n

المدونات

توصيات الكتب