Learn.Develop.Share

Twitter












dynamic - II - introduction

You remember the previous post on dynamic. We will today look into it in a bit more detail. Yeah, let's ILDASM it and try and identify what is going on under the hood. But for the context of the post let's look at a simpler tale.
 
namespace Coderslog.Net4.Samples
{
    public class SimpleDynamic
    {

        public void CallDoSomething()
        {
            var instance = GetDoSomething();
            instance.DoSometing();
        }

        private dynamic GetDoSomething()
        {
            return new BehaviourA();
        }
    }
}
A very basic class, hmmm which roughly translates to something like, I might not be absolutely correct, but to get a fair idea, it is something like the following
 
public class SimpleDynamic
{
    // Method: A Bit more involved than the reflection way, with Optimization    
    public void CallDoSomething()
    {
        object instance = this.GetDoSomething();
        if (CallDoSometning_SiteContainer.delegatePlaceHolder == null)
        {
            CallDoSometning_SiteContainer.delegatePlaceHolder =
                CallSite<Action<CallSite, object>>.Create
(
                        new CSharpInvokeMemberBinder
(
                                
CSharpCallFlags.None,
                                "
DoSometing",
                                typeof(
SimpleDynamic),
                                null
,
                                new []
                                        {
                                                
new CSharpArgumentInfo(
                                                        CSharpArgumentInfoFlags.None
                                                        , null
                                                )

                                        }
                        
));
        }
        CallDoSometning_SiteContainer.
                delegatePlaceHolder.
                        Target.Invoke(
                                CallDoSometning_SiteContainer.delegatePlaceHolder
                                , instance);
    }

    
    //But theres an attribute on the object of
    //Type:System.Runtime.CompilerServices.DynamicAttribute
    private object GetDoSomething()
    {
        return new BehaviourA();
    }

    // Nested Types
    //Compiler Generated Class- Internal Class
    private static class CallDoSometning_SiteContainer
    {
        // Fields
        public static CallSite<Action<CallSite, object>> delegatePlaceHolder;
    }

}
 
So as you can see, the internal static class is there so as to ensure that, we don't always spend resources on the delegate, once it is evaluated.
If we look at the GetDomethingMethod, the Dydnamic Attribute on the returned object from the method GetDoSomething tells the run time that "Indicates that the use of  Object on a member is meant to be treated as a dynamically dispatched type.". If you notice the type of the static field is of type CallSite<Action<CallSite, object>> is  System.Runtime.CompilerServices..::.CallSite<(Of <(T>)>) { MSDN: A dynamic call site base class. This type is used as a parameter type to the dynamic site targets.}.  
 
Lets look at the place where all the action is happening, i.e. the method  CallDoSomething. the method checks if the class CallDoSometning_SiteContainer.delegatePlaceHolder is populated or not, but if not it initializes it with the Create Method and you can notice ... CSharpInvokeMemberBinder {CompleteNamespace: Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder} {MSDN:  Represents a dynamic method call in C#, providing the binding semantics and the details about the operation. Instances of this class are generated by the C# compiler }.
 
This feels like .Net Reflection and one tends to ask, how optimized is it. Well, something Microsoft can enlighten us more about.


Feedback

No comments posted yet.