The two main terms appearing in the above topic are Late Binding and reflection. So let us first define these two terms. The binding of methods and objects during run time is called Late Binding or Dynamic Binding. Reflection is the ability of an assembly to inspect its metadata. Metadata contains the information of the data within the assembly.
Reflection is used to implement late binding as it allows you to use code that is not available at compile time. We will see the examples of this in the following code segments.
Example 1 : In this program, we make use of late binding because we do not have the knowledge of the class that has to be instantiated at compile time. Declare an object named executing of class Assembly and load the current Assembly using GetExecutingAssembly method. Next, we have to find the type of the class that has to be instantiated later i.e. Student. To do this use the method GetType on the object of Assembly class and store the type in another object called studentType. GetType method expects a String argument which is the complete name of the Class, LateBinding.Student in this case. Since the type is unknown at this point in the program we use the class Type to declare studentType. Now we create an instance of the studentType using the CreateInstance method that uses the type as a parameter. The Activator class contains methods to create types of objects locally or remotely or obtain references to existing remote objects. Next, create a MethodInfo object and use the GetMethod method to store the information. Pass the name of the method as an argument to GetMethod. To invoke GetDetails, use the MethodInfo object to call the Invoke method and pass studentObject as a parameter. And finally, display the details using a String det and also define the class.
C#
using System;
using System.Reflection;
namespace LateBinding {
class Program {
static void Main( string [] args)
{
Assembly executing = Assembly.GetExecutingAssembly();
Type studentType = executing.GetType( "LateBinding.Student" );
object studentObject = Activator.CreateInstance(studentType);
MethodInfo getMethod = studentType.GetMethod( "GetDetails" );
String[] param = new String[2];
param[0] = "1" ;
param[1] = "Lisa" ;
String det = (String)getMethod.Invoke(studentObject, param);
Console.WriteLine( "Student Details : " );
Console.WriteLine( "Roll Number - Name \n{0}" , det);
}
}
public class Student {
public String GetDetails(String RollNumber, String Name)
{
return RollNumber + " - " + Name;
}
}
}
|
Output: Student Details :
Roll Number - Name
1 - Lisa
Note: In the code above, if you do not define the class and build the code, it will build successfully since the binding is not done at compile time. But when you run it you will get an error as it will only be encountered at run time. The error message will be as follows;
Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: type
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at LateBinding.Program.Main(String[] args) in m:\Documents\Visual Studio 2012\Projects\LateBinding\LateBinding\Program.cs:line 19
Example 2: Another similar example is the code given below that has a Shape class and we are late binding the method shapeName.
C#
using System;
using System.Reflection;
namespace Geometry {
public class Shape {
public String shapeName(String sideNumber)
{
if (sideNumber == "0" || sideNumber == "1" || sideNumber == "2" )
return "Not Valid" ;
else if (sideNumber == "3" )
return "Triangle" ;
else if (sideNumber == "4" )
return "Quadrilateral" ;
else
return "Polygon" ;
}
}
class Program {
static void Main( string [] args)
{
Assembly executable = Assembly.GetExecutingAssembly();
Type shapeType = executable.GetType( "Geometry.Shape" );
object shapeObject = Activator.CreateInstance(shapeType);
MethodInfo shapeNameMethod = shapeType.GetMethod( "shapeName" );
String[] param = new String[1];
param[0] = "4" ;
String sName = (String)shapeNameMethod.Invoke(shapeObject, param);
Console.WriteLine( "Name of the Shape is {0}" , sName);
}
}
}
|
Output: Name of the Shape is Quadrilateral
Note: The disadvantage of Late Binding is that if you make any spelling error in the name of a method or class, the compiler will not identify it at compile time and therefore the code will build successfully. In most practical scenarios, Early Binding is used as opposed to Late Binding.