C# reflection


Release date:2023-09-02 Update date:2023-10-13 Editor:admin View counts:347

Label:

C# reflection

Reflection is the ability of a program to access, detect, and modify its ownstate or behavior.

Assemblies contain modules, which contain types, which in turn contain members. Reflection provides objects that encapsulate assemblies, modules, and types.

You can use reflection to dynamically create an instance of a type, bind a type to an existing object, or get a type from an existing object. You can then call the method of the type or access its fields and properties.

Advantages and disadvantages

Advantages:

  • 1.Reflection improves the flexibility and expansibility of the program.

  • 2.Reduce the coupling and improve the self-adaptive ability.

  • 3.It allows the program to create and control objects of any class without having to hard-code the target class in advance.

Disadvantages:

  • 1.Performance issues: using reflection is basically an interpretive operation, which is much slower than direct code for field and method access. Therefore, the reflection mechanism is mainly used in the system framework which requires high flexibility and expansibility, and it is not recommended by ordinary programs.

  • 2.The use of reflection will blur the internal logic of the program; programmers want to see the logic of the program in the source code, but reflection bypasses the technology of the source code, which will lead to maintenance problems, and the reflection code is more complex than the corresponding direct code.

The purpose of Reflection

Reflection has the following uses:

  • It allows you to view attribute information at run time.

  • It allows you to review the various types in the collection and instantiate them.

  • It allows you to delay bound methods and properties.

  • It allows you to create new types at run time and then use them to perform some tasks.

View metadata

As we have mentioned in the above section, you can view attribute information using Reflection.

System.Reflection analogous MemberInfo object needs to be initialized to discover class-related attribute. To do this, you can define an object of the target class, as follows:

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

The following program demonstrates this:

Example

using System;
[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
   public readonly string Url;
   public string Topic  // Topic is a named parameter
   {
      get
      {
         return topic;
      }
      set
      {
         topic = value;
      }
   }
   public HelpAttribute(string url)  // URL is a positional parameter
   {
      this.Url = url;
   }
   private string topic;
}
[HelpAttribute("Information on the class 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();
      }
   }
}

When the above code is compiled and executed, it displays attaching to the custom properties of class MyClass:

HelpAttribute

Example

In this example, we will use the DeBugInfo property and use Reflection to read the Rectangle metadata.

Example

using System;
using System.Reflection;
namespace BugFixApplication
{
   // A custom attribute BugFix is assigned to a class and its members
   [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
   {
      // Member variables
      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("Length: {0}", length);
         Console.WriteLine("Width: {0}", width);
         Console.WriteLine("Area: {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);
         // Traverse the properties of the Rectangle class
         foreach (Object attributes in type.GetCustomAttributes(false))
         {
            DeBugInfo dbi = (DeBugInfo)attributes;
            if (null != dbi)
            {
               Console.WriteLine("Bug no: {0}", dbi.BugNo);
               Console.WriteLine("Developer: {0}", dbi.Developer);
               Console.WriteLine("Last Reviewed: {0}",
                                        dbi.LastReview);
               Console.WriteLine("Remarks: {0}", dbi.Message);
            }
         }

         // Traverse method characteristics
         foreach (MethodInfo m in type.GetMethods())
         {
            foreach (Attribute a in m.GetCustomAttributes(true))
            {
               DeBugInfo dbi = (DeBugInfo)a;
               if (null != dbi)
               {
                  Console.WriteLine("Bug no: {0}, for Method: {1}",
                                                dbi.BugNo, m.Name);
                  Console.WriteLine("Developer: {0}", dbi.Developer);
                  Console.WriteLine("Last Reviewed: {0}",
                                                dbi.LastReview);
                  Console.WriteLine("Remarks: {0}", dbi.Message);
               }
            }
         }
         Console.ReadLine();
      }
   }
}

When the above code is compiled and executed, it produces the following results:

Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer: Nuha Ali
Last Reviewed: 10/10/2012
Remarks: Unused variable
Bug No: 45
Developer: Zara Ali
Last Reviewed: 12/8/2012
Remarks: Return type mismatch
Bug No: 55, for Method: GetArea
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks: Return type mismatch
Bug No: 56, for Method: Display
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks:

Powered by TorCMS (https://github.com/bukun/TorCMS).