How-To: Dynamic without dynamic

I am sure that by now you all heard about the new C# 4.0 feature called dynamic. In short, dynamic is the new feature in C# 4.0 that allows you to defer member binding until runtime.

The way you use this feature is very straight forward. If you have a class C with a method M and you want to call the method M but defer the binding until runtime, you would write this:

    1:  dynamic d = new C();
    2:  d.M();

What happens is that the compiler will notice that you are trying to do a late-bound call and will generate some code behind the scenes that will capture all the necessary information to allow the late binding to succeed.

The information is captured inside a CallSite object, and this is what such an object contains:

  • The type of the operation you want to bind (method call, property set, etc)
  • Is the method you are calling static
  • The name of the method you want to call
  • The context where the call was made (the class that contains the call). This is used to determine if a call to a private method should be allowed
  • The type arguments of the method (if any)
  • The type of all the arguments for the method call

There is nothing stopping you from creating such a structure by yourself in your code. You would have to write something like this:

    1:  var callM = CallSite<Action<CallSite, object, object>>.Create(
    2:      new CSharpInvokeMemberBinder(
    3:          CSharpCallFlags.None, 
    4:          "M", 
    5:          typeof(Program), 
    6:          null, 
    7:          new CSharpArgumentInfo[] { 
    8:                  new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) 
    9:          }
   10:      )
   11:  );

Besides all the information that is captured already, one interesting bit of information is decoded from using the Action delegate. By using Action we are specifying that we don’t care about the result of the operation (or that the return type of the method is void). If we did want to get back a result from the operation, we would have had to use Func instead of Action.

Now that all the necessary information is available inside the callM object we can execute the method using late binding. To do that, we simply do this:

    1:  object obj = new C();
    2:  callM.Target(callM, obj);

f you run this code you will be calling the method M using late binding. And that’s how you do dynamic without dynamic