Dynamic Language Runtime in C#

Discussion in 'C#' started by MinalS, Apr 2, 2015.

  1. MinalS

    MinalS New Member

    Joined:
    Jul 8, 2014
    Messages:
    138
    Likes Received:
    32
    Trophy Points:
    0
    The .NET framework 4.5 has namespace as System.Dynamic which contains the DLR. The following diagram shows the dynamic language runtime in C#.

    [​IMG]

    The dynamic language runtime consists of following components.
    1. Expression Trees: It is similar to the expression trees used in LINQ query
    2. Call Site Caching: It is useful for improving the efficiency of the site
    3. Dynamic Dispatch: It is used to dispatch the invoked components to the appropriate binder
    The top level of DLR consists of dynamic languages and their capabilities. The languages like C#, Python, and VB.NET are supported. There are several binders used in various technologies as mentioned below:
    1. .NET Binder: The .NET binder takes various .NET objects.
    2. JavaScript Binder: It helps user to work on JavaScript
    3. COM Binder: It is used with the COM objects
    Dynamic Type

    The dynamic type helps user to write code that can easily execute through compile time type checking. The operations executed on the dynamic type are always considered as valid by the compiler. The error is not identified till the runtime.

    The following code shows the dynamic type in C#.
    Code:
    class Program
    {
        static void Main( string [ ] args )
        {
            var staticStudent = new Student();
            dynamic dynamicPerson = new Student();
            staticStudent.GetName("Mark");
            dynamicStudent.GetName("Mark");
        }
    }
    
    class Person
    {
        public string Name { get; set; }
        public string GetName()
        {
            public string GetName()
            {
                return string.Concat("Welcome", " " +, Name);
            }
        }
    }
    
    In the above code, it will not compile because the staticStudent.GetName is the call. The var keyword is used on an object defined as dynamic. If user defines the type as dynamic, the type can be changed number of times. The object can be cast from one data type to object data type.

    The following example demonstrates the type casting from one type to another.
    Code:
    dynamic dyn;
    dyn = 50;
    
    Console.WriteLine(dyn.GetType());
    Console.WriteLine(dyn);
    dyn = " A string data type";
    Console.WriteLine("dyn.GetType());
    Console.WriteLine(dyn);
    
    When the above code is executed, the Integer type is converted to string type. If the dynamic object was declared as integer or string, it would be a compile error.

    DynamicObject

    The dynamic object helps compiler to perform the late binding mechanism. The execution is checked at the runtime. The actual data type of the object is not known till the runtime. The object inherits from the DynamicObject.

    Some of the methods of the DynamicObject class are mentioned below:
    1. Finalize: It helps the object to try to release resources and do the cleanup operations before garbage collection
    2. GetDynamicMembersName: It provides user with the enumeration of all the dynamic member names
    3. TryBinaryOperation: It provides user with the binary operation implementation
    4. TryCreateInstance: It provides user with the implementation of the operations used for initializing the the dynamic object
    5. TryGetIndex: It gives the implementation for operations used for deleting the object member
    6. TrySetIndex: It gives implementation for operations to set the value by index
    Consider an example to demonstrate the DynamicObject in C#.
    Code:
    
    class DynamicObject1 : DynamicObject
    {
        Dictionary<string, object> _data = new Dictionary<string, object>();
        
        public override bool GetMember(GetMemberBinder binder, out object output)
        {
            bool success=false;
            output = null;
            if( _dynamicData.ContainsKey(binder.Name))
            {
                output = _data(binder.Name);
                success = true;
            }
            else
            {
                output = " Value not found";
                success=false;
            }
        }
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            _data[binder.Name] = value;
            return true;
        }
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[ ] 
        args, out object output)
        {
            dynamic method = _data[binder.Name];
            output = method( ( DateTime) args [0] );
            return output ! = null;
        }
    
    }
    
    In the above code, user overrides three methods as TrySetMember, TryGetMember, TryInvokeMember. The TrySetMember adds a method, property or field to an object. The Dictionary object is used in the code for storing the information about member.

    The SetMemberBinder object passes to the TrySetMember method containing the Name property used for identifying the element in the Dictionary. The TryGetMember is used for retrieving the object stored in the Dictionary based on the GetMemberBinder Name property.

    The following code sample makes use of the dynamic object created by user.
    Code:
    dynamic dyn1 = new DynamicObject1();
    dyn1.FirstName="Harry";
    dyn1.LastName="Potter";
    Console.WriteLine(dyn1.GetType());
    Console.WriteLine("{0},{1}", dyn1.FirstName, dyn1.LastName);
    
    ExpandoObject

    The coding of ExpandoObject is much similar to that of the DynamicObject. It represents an object where the members can be dynamically added and deleted at the runtime. The methods cannot be overridden in the ExpandoObject.

    Some of the properties of the ExpandoObject are as shown below:
    1. ICollection<KeyValuePair<String, Object>>.Count: It gets the number of elements in the collection
    2. IDictionary<String, Object>.Keys: It gets a collection containing the keys of the IDictionary<TKey, TValue>
    3. IDictionary<String, Object>.Values: It gets a collection that contains values in the IDictionary<TKey, TValue>
    Some of the methods of the ExpandoObject are as mentioned below:
    1. ToString: It returns the string representing the current object
    2. GetType: It gets the type of the current instance
    3. GetHashCode: It provides a default hash function
    4. Equals(Object): It checks whether the specific object is equal to the current object
    5. All<KeyValuePair><String, Object>>: It checks whether the elements satisfy the condition
    6. AsParallel(): It enables parallelization of the query.
    7. AsQueryable(): It converts the IEnumerable to an IQueryable
    8. Cast<TResult>: It casts the elements of the IEnumerable to the type specified
    9. Last<KeyValuePair<String, Object>>(): It returns the last element of the sequence
    Event in the ExpandoObject - INotifyPropertyChanged.PropertyChanged: It occurs when the property value is changed

    Consider an example to demonstrate the ExpandoObject in C#.
    Code:
    class Program
    {
        public static void Expando1()
        {
            Dynamic dyn2 = new ExapndoObject();
            dyn2.FirstName="Liza";
            dyn2.LastName="Damiano"
            Console.WriteLine(dyn2.FirstName + " " + dyn2.LastName);        
        }
    }
    
    In the above code, user can create an empty ExpandoObject and the values are assigned later. In DynamicObject type, the user needs to call the GetType to access the type assigned.

    Enumeration and deletion of members in ExpandoObject is possible. The class implements the IDictionary<String, Object> interface. User can assign the instance of the object at runtime.

    Consider the following example to demonstrate the casting of an instance and enumerating them.
    Code:
    dynamic student = new ExpandoObject();
    student.Name = "John";
    student.Class = 10;
    
    foreach ( var prp1 in (IDictionary<String, Object>student)
    {
        Console.WriteLine(prp1.Key+" " +prp1.Value);
    }
    
    User can delete the member by implicitly casting the instance of the object. The following code snippet demonstrates the functionality.
    Code:
    dynamic student = new ExpandoObject();
    student.Name = "John";
    ((IDictionary<String, Object>) student ).Remove("Name") ;
    
    The changes in the property can be notified to the user. The object class implements the INotifyPropertyChanged interface. A PropertyChanged event is raised when the member is added, deleted or modified.

    The following code implements the creation of an event handler for the event.
    Code:
    class Program
    {
        static void Process()
        {
            dynamic student = new ExpandoObject();
            (( INotifyPropertyChanged)order).PropertyChanged += new PropertyChangedEventHandler(HandlePropertyChanges);
            student.Name = "Harry";
        }
        private static void HandlePropertyChanges( object sender, PropertyChangedEventArgs e )
        {
            Console.WriteLine("{0}", the modified value is", e.PropertyName);
        }
    }
    
     
    Last edited by a moderator: Jan 21, 2017

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice