Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Part 55 - C# Tutorial - Late binding using reflection

In this session we will understand
1. Early binding and late binding
2. The difference between the two approaches


Early Binding Example:
using System;
namespace Pragim
{
    public class MainClass
    {
        private static void Main()
        {
            Customer C1 = new Customer();
            string fullName = C1.GetFullName("Pragim", "Tech");
            Console.WriteLine("Full Name = {0}", fullName);
        }
    }
    public class Customer
    {
        public string GetFullName(string FirstName, string LastName)
        {
            return FirstName + " " + LastName;
        }
    }
}

Part 55 - C# Tutorial - Late binding using reflection



In this example, we have the knowledge of Customer class at compile time. So, we are able to create the instance of the Customer class using the new operator. We are also able to invoke the GetFullName() method using C1. Intellisense detects the presence of this method and the number and type of parameters that need to be passed in. If you make any mistake in the name of the method, or the number and type of parameters, those mistakes will be immediately raised as compiler errors.


Late Binding Example:
using System;
using System.Reflection;
namespace Pragim
{
    public class MainClass
    {
        private static void Main()
        {
            // Load the current executing assembly as the Customer class is present in it.
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            // Load the Customer class for which we want to create an instance dynamically
            Type customerType = executingAssembly.GetType("Pragim.Customer");
            // Create the instance of the customer type using Activator class 
            object customerInstance = Activator.CreateInstance(customerType);
            // Get the method information using the customerType and GetMethod()
            MethodInfo getFullName = customerType.GetMethod("GetFullNames");
            // Create the parameter array and populate first and last names
            string[] methodParameters = new string[2];
            methodParameters[0] = "Pragim"; //FirstName
            methodParameters[1] = "Tech";     //LastName
            // Invoke the method passing in customerInstance and parameters array
            string fullName = (string)getFullName.Invoke(customerInstance, methodParameters);
            Console.WriteLine("Full Name = {0}", fullName);
        }
    }
    public class Customer
    {
        public string GetFullName(string FirstName, string LastName)
        {
            return FirstName + " " + LastName;
        }
    }
}


Let's assume we don't have the knowledge of Customer class at compile time, and it will be provided only at run time. In this case we need to bind to the Customer class at runtime. 
1. Load the assembly which contains the Customer class. In our case, the Customer class is present in the same assembly as the MainClass. So, we use Assembly.GetExecutingAssembly() to load the current executing assembly. On the Assembly class, there are several static methods which can be used to load an assembly at runtime dynamically.
2. Next, we load the Customer class for which we want to create an instance dynamically using executingAssembly.GetType("Pragim.Customer"). Make sure you pass in the fully qualified name to the GetType() method, including the namespace. Otherwise you risk getting a NullReferenceException at runtime.
3. Create the instance of the Customer class using Activator.CreateInstance(customerType).
4. Once we have the Customer instance, now get the method information which we want to invoke dynamically. we use customerType.GetMethod("GetFullName").
5. The GetFullName() method expects 2 string parameters. So, we need to create a string array,  and populate it with the first and last name parameters.
6. Finally, invoke the method passing in customerInstance and parameters array.


If you mis-spell the method name or if you pass in the wrong number or type of parameters, you wouldn't get a compiler error, but the application crashes at runtime.


Difference between early and late binding:
1. Early binding can flag errors at compile time. With late binding there is a risk of run time exceptions.
2. Early binding is much better for performance and should always be preferred over late binding. Use late binding only when working with onjects that are not available at compile time.

10 comments:

  1. Why would you not have knowledge of the class at compile time and only at run time? Is there a good example of that?

    ReplyDelete
  2. if you have to access say VB6 dll function in .net code you will have to use reflection.

    ReplyDelete
  3. If I don't have knowledge of "Pragim.Customer" how can I design a program around an unknown?

    ReplyDelete
  4. This code snippet does not work to well if the arguments in the target class are Double, int...even if you set up the method parameters as:
    double[] methodParameters = new double[2] and populated as such. In this case, we need to create a object[2] and put the individual doubles into it and then use this version of methodParameters in the Invoke call.

    ReplyDelete
  5. For reflection the better example would be mvc routing . once request comes to controller , from route table we have only name of controller and action. with those names we should get controller and action and have to invoke that action. this can be possible by reflection only.

    ReplyDelete
  6. Hi Venkat,
    If we don't have knowledge of class at compile time, its obvious that we don't have knowledge of methods in that (eg method name, parameters, return type etc) So how to use Late Binding using Reflection in that case. I can't figure out whats the use of Reflection on Late Binding. Can you please elaborate more focus on that.

    ReplyDelete
    Replies
    1. This is how we use it. We use a standard method name in classes in many forms that wants to be notified every time a value of certain element changes. Each class performs different actions on private objects of that class. All classes that need to be notified of changes register with the primary controller. Controller then invokes the same procedure in all registered classes without having to know what it does with the passed value. This way when we add new forms and classes all we have to do is register with controller and nothing has to be done on the controller side or anywhere else in the code.

      Delete
    2. I have used reflection extensively in my project. We have more than 5000 different node of XML. In each node, there are different attributes which represents fields of pdf file. On the run time, we extract each attributes with its properties like which method is responsible for filling data in corresponding field on PDF file. All the functions are already defined and we write a single for loop to invoke method attached to any field to fill it's data. Otherwise, it would have been arduous to handle such a large number of fields with static binding.

      Delete
  7. What happens if you have over load function of "GetFullName"

    ReplyDelete
  8. To run the above Late Binding Example code successfully, change the line which reads:
    MethodInfo getFullName = customerType.GetMethod("GetFullNames");
    to
    MethodInfo getFullName = customerType.GetMethod("GetFullName");

    Changing GetFullNames to GetFullName...

    ReplyDelete

It would be great if you can help share these free resources