C# Reflection

Reflection objects in C# are mainly used to obtain type information at runtime in the system. These classes which allow access to metadata of any running program are meant to be in the System.Reflection namespaces. We can also say that Reflection is capable to get the type of information that describes different modules, parameters, and members by examining their metadata in the managed code.

Reflection Properties:

Given below are the important properties of reflection in C#.

  • Reflection is capable to get the type of information that describes different modules, members and parameters by examining their meta data.
  • Reflection can create type instances dynamically at runtime and bring on its methods or access its fields and properties.
  • Reflection allows late binding to methods and properties.
  • Reflection allows to view attribute information at runtime.
  • Reflection allows to create new types at runtime and then performs some tasks using those types.
using System;
using System.Reflection;

namespace BugFixApplication {
   //custom attribute BugFix used to be assigned to a class along with its class members
   [AttributeUsage(
      AttributeTargets.Class |
      AttributeTargets.Method |
      AttributeTargets.Field |
	  AttributeTargets.Constructor |
      AttributeTargets.Property,
      AllowMultiple = true)]

   public class DeBugInfo : System.Attribute {
      private int bugNo;
      private string developer;
      
      public string message;
      
      public DeBugInfo(int bg, string dev, string d) {
         this.bugNo = bg;
         this.developer = dev;
         
      }
      public int BugNo {
         get {
            return bugNo;
         }
      }
      public string Developer {
         get {
            return developer;
         }
      }
    
      public string Message {
         get {
            return message;
         }
         set {
            message = value;
         }
      }
   }
   [DeBugInfo(32, "Alice", "9/4/2021", Message = "Return type mismatch")]
   [DeBugInfo(42, "John", "2/12/2021", Message = "Unused variable")]
   
   class Rectangle {
      //member of variables
	   protected double width;
      protected double length;
      
      public Rectangle(double w, double l) {
        width = w;
		  length = l;
               }
      [DeBugInfo(48, "Alice", "9/4/2021", Message = "Return type mismatch")]
      public double GetArea() {
         return length * width;
      }
      [DeBugInfo(53, "Alice", "9/4/2021")]
      public void Display() {
         Console.WriteLine("Length: {0}", length);
         Console.WriteLine("Width: {0}", width);
         Console.WriteLine("Area: {0}", GetArea());
      }
   }
   
 public  class ExecuteRectangle {
   public   static void Main(string[] args) {
         Rectangle r = new Rectangle(9.2, 5.7);
         r.Display();
         Type type = typeof(Rectangle);
         
         //iterating of the Rectangle class through the attribtues 
         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);

            }
		 }
         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);
                
               }
            }
         }
      }
   }
}