Reflection And Late Binding In C#

Introduction

 
Reflection concept in C# is ability of inspecting metadata of an assembly at runtime. In other words, an assembly content is described by looking at the assembly metadata at runtime by loading a library in memory and reading its attributes. In this article, I'll try to explain refection concepts and the how can it be useful in applications.
 
When it comes to use reflection in practice scenarios it is very confusing for the developers to use refection concept properly and get benefit for this beautiful feature. However, reflection is not recommend in obvious conditions. It may slow the performance of an application.
 

Reflection in C#

 
Reflection is the ability of a managed code to read its own metadata for the purpose of finding assemblies, modules and type information at runtime. The classes that give access to the metadata of a running program are in System.Reflection.

System.Reflection namespace defines the following types to analyze the module's metadata of an assembly: Assembly, Module, Enum, ParameterInfo, MemberInfo, Type, MethodInfo, ConstructorInfo, FieldInfo, EventInfo, and PropertyInfo.
 

Assembly Metadata


An assembly is a logical DLL or EXE, which is described by manifest, the detailed description (metadata) of an assembly. The .NET compiler produces a portable executable PE file for CLR with the extensions of .exe or .dll. This PE file is mainly comprised of metadata and IL (Intermediate Language).

Explanation
 
When a compiler builds a binary (dll or exe), the code gets complied into the Intermediate Language (IL) and then packaged in an assembly. An assembly contains metadata which has the information about the type of classes and their definitions including their members, fields, constructors, properties, methods, function etc.

By using refection, an assembly can be inspected.
  1. Type _type = Type.GetType("ReflectionConcept.Employee");  
  2. Or  
  3. Type _type = typeof(Employee);  

Assembly Metadata

Sample Code
  1. namespace ReflectionConcept  
  2. {  
  3.     public class Employee  
  4.     {  
  5.         public int empID { getset; }  
  6.         public string empName { getset; }  
  7.         public float Salary { getset; }  
  8.   
  9.         public Employee()  
  10.         {  
  11.             this.empID = -1;  
  12.             this.empName = string.Empty;  
  13.             this.Salary = 0;  
  14.         }  
  15.   
  16.         public Employee(int id, string name, float salary)  
  17.         {  
  18.             this.empID = id;  
  19.             this.empName = name;  
  20.             this.Salary = salary;  
  21.         }  
  22.   
  23.         public void displayName()  
  24.         {  
  25.             Console.WriteLine("Name :" + this.empName);  
  26.         }  
  27.   
  28.         public void printSalary()  
  29.         {  
  30.             Console.WriteLine("Salary :" + this.Salary);  
  31.         }  
  32.   
  33.     }  
  34.   
  35.     class Program  
  36.     {  
  37.         static void Main(string[] args)  
  38.         {  
  39.            Type _type = Type.GetType("ReflectionConcept.Employee");  
  40.   
  41.            // Type _type = typeof(Employee);  
  42.   
  43.   
  44.             Console.WriteLine(_type.FullName);  
  45.             Console.WriteLine(_type.Namespace);  
  46.             Console.WriteLine(_type.Name);  
  47.   
  48.             PropertyInfo[] info  = _type.GetProperties();  
  49.   
  50.             foreach (PropertyInfo propinfo in info)  
  51.             {  
  52.                 Console.WriteLine(propinfo.Name);  
  53.             }  
  54.   
  55.             MethodInfo [] methods=_type.GetMethods();  
  56.   
  57.             foreach (MethodInfo methodinfo in methods)  
  58.             {  
  59.                 Console.WriteLine(methodinfo.ReturnType.Name);  
  60.                 Console.WriteLine(methodinfo.Name);  
  61.             }  
  62.   
  63.             Console.ReadLine();  
  64.         }          
  65.     }  

Uses of Reflections

 
A. Refection is heavily used by develoepr IDEs or UI designers such as Visual Studio. The Property window of a .NET application uses refection to show list of properties.

Still confused….alright let me take an example of a Web application.

In a Web application, whenever developers drags and drop a control from Toolbox to the Form, the code is written for you. Here reflection plays the role and used to read control properties and events. Thease are listed in the Properties window.

Uses of Reflections

B. Late binding can be achieved by using refection. Meaning, reflection gives developers a way to use code that is not available at compile time. By using refection, the new instances of types can be created dynamically, which don’t have information at compile time.

Important Sticky
  • It allows view attribute information at runtime.
  • It allows examining various types in an assembly and instantiate these types.
  • It allows late binding to methods and properties
  • It allows creating new types at runtime and then performs some tasks using those types.

Late binding using reflections

Before learning late binding, let us have look at early binding. Early Binding can be explained in a way that the compiler knows about what kind of objects it is, what an object members and types are. Auto Intellisense is an example where developers can see all availalbe members of a class when typing in the editor. 
  1. Employee emp = new Employee();  
  2.   emp.displayName(); 

Late binding is nothing but binding at run time. Compiler does not know what kind of object it is, what are all the methods and properties it contains. Late binding is achieved by using reflections.

Sample Code

  1. namespace ReflectionConcept  
  2. {  
  3.     public class Employee  
  4.     {  
  5.         public int empID { getset; }  
  6.         public string empName { getset; }  
  7.         public float Salary { getset; }  
  8.   
  9.         public Employee()  
  10.         {  
  11.             this.empID = -1;  
  12.             this.empName = string.Empty;  
  13.             this.Salary = 0;  
  14.         }  
  15.   
  16.         public Employee(int id, string name, float salary)  
  17.         {  
  18.            this.empID = id;  
  19.             this.empName = name;  
  20.             this.Salary = salary;  
  21.         }  
  22.   
  23.         public void displayName()  
  24.         {  
  25.             Console.WriteLine("Name :" + this.empName);  
  26.         }  
  27.   
  28.         public void displayemp(string name)  
  29.         {  
  30.             Console.WriteLine("Name :" + name);  
  31.         }  
  32.   
  33.   
  34.         public void printSalary()  
  35.         {  
  36.             Console.WriteLine("Salary :" + this.Salary);  
  37.         }  
  38.   
  39.     }  
  40.   
  41.     class Program  
  42.     {  
  43.         static void Main(string[] args)  
  44.         {  
  45.             Assembly exceutable = Assembly.GetExecutingAssembly();  
  46.             Type Ltype =exceutable.GetType("ReflectionConcept.Employee");  
  47.   
  48.             object objEmployee = Activator.CreateInstance(Ltype);  
  49.   
  50.             MethodInfo method = Ltype.GetMethod("displayemp");  
  51.   
  52.             string[] parameter = new string[1];  
  53.   
  54.             parameter[0] = "Abhishek";  
  55.   
  56.            string employeeName=   (string)method.Invoke(objEmployee, parameter);  
  57.   
  58.                 Console.ReadLine();  
  59.         }  
  60.           
  61.     }  

Early Binding Vs Late Binding

  • Performance will be good in early binding.
  • Application will run faster in early binding, since no boxing or unboxing is done here but in late binding we need type conversion as it will be decoded at run time.
  • Easier to write the code in early binding, since the intelligence will be automatically populated
  • Less chances errors in early binding, as syntax is checked which flags error at compile time itself but for late binding there are chances of run time exceptions.
  • Late binding would support in all kind of versions, due to handing at run time.
  • Minimal Impact of code in future enhancements, if late binding is used.

Conclusion

In this article, we've compared early binding and late binding features and found late binding is complex need more lines of code, venerable to run time exceptions, have issues with performance and does not support auto-intellisense in the designer.
 
So it is very important to understand where late binding should be used. The answer is when we are working with objects that are not available at compile time.