Dynamic in C# – Part3

Posted: September 19, 2009 in .NET, C#
Tags: , ,

In the last two posts we have discussed about dynamic languages and how DLR allows dynamic languages to run on CLR.In this post we will take a look into the new “dynamic” type in C# and how it works internally.

Let us take a look into the following lines of code:

class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.TestMethod(new Foo());
t.TestMethod(new Bar());
Console.ReadLine();
}
}
class Test
{
public void TestMethod(dynamic d)
{
d.DynamicMethod();
}
}
class Foo
{
public void DynamicMethod()
{
Console.WriteLine("Foo:: Print");
}
}

Here the method TestMethod accepts a dynamic object as parameter and invokes a method called DynamicMethod on it.The actual type of “d” is determined at runtime and the appropriate method will be executed.As I have explained in the previous post the following steps will be performed at runtime:

  • The control will be passed to the CallSite and CallSite will pass the control to the C# Runtime Binder.
  • C# Runtime Binder will make use of Reflection and determine the actual type of the object.
  • It will check for the method to be executed.If the type does not support that method it will throw the following exception:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : ‘object’ does not contain a definition for ‘DynamicMethod’

  • Based on the type it will build the expression to be executed and this will be stored in CallSite cache for any further reference.

Now the obvious question that comes is how dynamic CallSite is getting plugged into this code.This is done by the compiler behind the scenes.Analysing the code using reflector gives the following view of the class Test

internal class Test
{
// Methods
public void TestMethod([Dynamic] object d)
{

//Check if CallSite is already instantiated
if (<TestMethod>o__SiteContainer0.<>p__Site1 == null)
{

//Create the CallSite and Bind it with the method DynamicMethod
<TestMethod>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(new CSharpInvokeMemberBinder(CSharpCallFlags.None, "DynamicMethod", typeof(Test), null, new CSharpArgumentInfo[] { new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
}
<TestMethod>o__SiteContainer0.<>p__Site1.Target(<TestMethod>o__SiteContainer0.<>p__Site1, d);
}

// Nested Types
[CompilerGenerated]
private static class <TestMethod>o__SiteContainer0
{
// Fields
public static CallSite<Action<CallSite, object>> <>p__Site1;
}
}

The class o__SiteContainer0 is a nested class generated by the compiler and it exposes a static property of type CallSite.Within the method TestMethod the CallSite is created and bound the DynamicMethod.The call d.DynamicMethod is then replaced by setting the Target of the CallSite.

In this post we have covered how dynamic keyword is used and it’s high level implementation.But here we have omitted one scenario where the dynamic object implements IDynamicObject interface.In that case implementation will be different and we will cover it in the next post.

Advertisements
Comments
  1. Dynamic in C# – Part3…

    DotNetBurner – burning hot .net content…

  2. I’ve been looking so many places for thsi information.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s