English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

دليل أساسي لتعلم C#

دليل متقدم لتعلم C#

C# موجه نحو الأوبجكت (OOP)

الاستعراض في C#

التفكير الت反射ي (Reflection) هو القدرة التي يمكن للبرنامج من خلالها الوصول إلى، التحقق من، وتعديل حالة أو سلوكه.

المجموعة تحتوي على الوحدات، والوحدات تحتوي على الأنواع، والأنواع تحتوي على العناصر. يوفر التفكير الت反射ي (Reflection) كائنات لتبطين المجموعات والوحدات والأنواع.

يمكنك استخدام التفكير الت反射ي (Reflection) لإنشاء نماذج أنواع ديناميكية، وتقييد الأنواع إلى كائنات موجودة، أو استخراج الأنواع من كائنات موجودة. ثم يمكنك استدعاء أساليب النوع أو الوصول إلى حقولها وخصائصها.

المزايا والعيوب

المزايا:

  • 1- يزيد من مرونة البرنامج وتوسعه.

  • 2- يقلل من التشابك، ويزيد من القدرة على التكيف.

  • 3- يسمح للبرنامج بإنشاء وتحكم بأي كائن من أي فئة دون الحاجة إلى كتابة كود مسبق لهدف الفئة.

العيوب:

  • 1- مشكلة الأداء: باستخدام التفكير الت反射ي (Reflection) يعتبر نوعًا من العمليات التفسيرية، ويعتبر الأداء أبطأ بكثير من الكود المباشر عند الوصول إلى الحقول والأساليب. لذلك، يتم استخدام ميكانيكية التفكير الت反射ي (Reflection) بشكل رئيسي في الأنظمة التي تتطلب مرونة وتوسعًا عاليًا، حيث لا يُنصح باستخدامها في البرامج العادية.

  • 2- مشكلة الأداء: باستخدام التفكير الت反射ي (Reflection) يعتبر نوعًا من العمليات التفسيرية، ويعتبر الأداء أبطأ بكثير من الكود المباشر عند الوصول إلى الحقول والأساليب. لذلك، يتم استخدام ميكانيكية التفكير الت反射ي (Reflection) بشكل رئيسي في الأنظمة التي تتطلب مرونة وتوسعًا عاليًا، حيث لا يُنصح باستخدامها في البرامج العادية.

استخدامات التفكير الت反射ي (Reflection)

يستخدم التفكير الت反射ي (Reflection) للغايات التالية:

  • إنه يسمح بعرض معلومات الصفات (الصفات) عند تشغيل البرنامج.

  • إنه يسمح بمراجعة أنواع مختلفة في المجموعة، وكذلك إنشاء أنواع.

  • إنه يسمح بربط الأساليب والصفات (الخصائص) بصورة متأخرة.

  • إنه يسمح بإنشاء أنواع جديدة عند تشغيل البرنامج، ثم تنفيذ بعض المهام باستخدام هذه الأنواع.

مراجعة البيانات التكميلية

لقد ذكرنا في الفصل السابق أن استخدام التفكير الت反射ي (Reflection) يمكنه عرض معلومات الصفات.

System.Reflection فئة MemberInfo العدد يجب أن يتم تفعيله، لاستكشاف الخصائص (الصفات) المرتبطة بالفئة. من أجل القيام بذلك، يمكنك تعريف هدف فئة واحدة، مثلما هو موضح أدناه:

System.Reflection.MemberInfo info = typeof(MyClass);

برنامج التدريب التالي يوضح ذلك:

using System;
[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
   public readonly string Url;
   public string Topic  // Topic هو معامل مسمى (named)
   {
      get
      {
         return topic;
      }
      set
      {
         topic = value;
      }
   }
   public HelpAttribute(string url)  // url هو معامل مطلق (positional)
   {
      this.Url = url;
   }
   private string topic;
}
[HelpAttribute("معلومات حول فئة MyClass")]
class MyClass
{
}
namespace AttributeAppl
{
   class Program
   {
      static void Main(string[] args)
      {
         System.Reflection.MemberInfo info = typeof(MyClass);
         object[] attributes = info.GetCustomAttributes(true);
         for (int i = 0; i < attributes.Length; i++)
         {
            System.Console.WriteLine(attributes[i]);
         }
         Console.ReadKey();
      }
   }
}

عندما يتم تجميع وكتابة الكود أعلاه تنفذه، سيقوم بعرض الصفات المضافة إلى الكائن MyClass على الصفات المخصصة:

HelpAttribute

مثال على الإنترنت

في هذا المثال، سنستخدم الذي تم إنشاؤه في الفصل السابق DeBugInfo الصفات، واستخدام التفكير في العكس (Reflection) لقراءتها مستطيل المعلومات المتراكبة في الكائن.

using System;
using System.Reflection;
namespace BugFixApplication
{
   // 一个自定义特性 BugFix 被赋给类及其成员
   [AttributeUsage(AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property,
   AllowMultiple = true)]
   public class DeBugInfo : System.Attribute
   {
      private int bugNo;
      private string developer;
      private string lastReview;
      public string message;
      public DeBugInfo(int bg, string dev, string d)
      {
         this.bugNo = bg;
         this.developer = dev;
         this.lastReview = d;
      }
      public int BugNo
      {
         get
         {
            return bugNo;
         }
      }
      public string Developer
      {
         get
         {
            return developer;
         }
      }
      public string LastReview
      {
         get
         {
            return lastReview;
         }
      }
      public string Message
      {
         get
         {
            return message;
         }
         set
         {
            message = value;
         }
      }
   }
   [DeBugInfo(45, "Zara Ali", "12/8/2012",
        Message = "Return type mismatch")]
   [DeBugInfo(49, "Nuha Ali", "10/10/2012",
        Message = "Unused variable")]
   class Rectangle
   {
      // 成员变量
      protected double length;
      protected double width;
      public Rectangle(double l, double w)
      {
         length = l;
         width = w;
      }
      [DeBugInfo(55, "Zara Ali", "19/10/2012",
           Message = "Return type mismatch")]
      public double GetArea()
      {
         return length * width;
      }
      [DeBugInfo(56, "Zara Ali", "19/10/2012")]
      public void Display()
      {
         Console.WriteLine("الطول: {0}", length);
         Console.WriteLine("العرض: {0}", width);
         Console.WriteLine("المساحة: {0}", GetArea());
      }
   // end class Rectangle  
   
   class ExecuteRectangle
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(4.5, 7.5);
         r.Display();
         Type type = typeof(Rectangle);
         // مرور على خصائص شكل المربع
         foreach (Object attributes in type.GetCustomAttributes(false))
         {
            DeBugInfo dbi = (DeBugInfo)attributes;
            if (null != dbi)
            {
               Console.WriteLine("رقم الخطأ: {0}", dbi.BugNo);
               Console.WriteLine("مطور: {0}", dbi.Developer);
               Console.WriteLine("آخر مراجعة: {0}",
                                        dbi.LastReview);
               Console.WriteLine("ملاحظات: {0}", dbi.Message);
            }
         }
         
         // مرور على خصائص الطريقة
         foreach (MethodInfo m in type.GetMethods())
         {
            foreach (Attribute a in m.GetCustomAttributes(true))
            {
               DeBugInfo dbi = (DeBugInfo)a;
               if (null != dbi)
               {
                  Console.WriteLine("رقم الخطأ: {0}, للطريقة: {1}",
                                                dbi.BugNo, m.Name);
                  Console.WriteLine("مطور: {0}", dbi.Developer);
                  Console.WriteLine("آخر مراجعة: {0}",
                                                dbi.LastReview);
                  Console.WriteLine("ملاحظات: {0}", dbi.Message);
               }
            }
         }
         Console.ReadLine();
      }
   }
}

عندما يتم تجميع وكود التنفيذ، سيتم إنتاج النتيجة التالية:

الطول: 4.5
العرض: 7.5
المساحة: 33.75
رقم الخطأ: 49
مطور: Nuha Ali
آخر مراجعة: 10/10/2012
التعليقات: المتغير غير المستخدم
رقم الخطأ: 45
المطور: Zara Ali
آخر مراجعة: 12/8/2012
التعليقات: عدم تطابق نوع العودة
رقم الخطأ: 55، للطريقة: GetArea
المطور: Zara Ali
آخر مراجعة: 19/10/2012
التعليقات: عدم تطابق نوع العودة
رقم الخطأ: 56، للطريقة: Display
المطور: Zara Ali
آخر مراجعة: 19/10/2012
التعليقات: