C# 4.0 Goodness: The dynamic Type, The DLR, and The ExpandoObject Type

November 10th, 2009 by jason Leave a reply »

I have been playing around with C# 4.0 Beta 2 and stumbled onto the ExpandoObject (in the System.Dynamic namespace, System.Core assembly).  The object is built to be used in the DRL (Dynamic Language Runtime).  The DLR is a way for strongly-typed code to play nicely with weakly-typed code like IronPython, and vice-versa.  In C# 4.0 the dynamic keyword is used to reference objects that are weakly typed, and the ExandoObject is a .Net class that pretends to be a weakly-typed object.

ExpandoObject allows for addition of member properties and methods are run-time similar to popular scripting languages like Javascript.  Yet ExpandoObject is a real .Net type, and implements a couple of  interesting .Net interfaces: IDictionary<string, object> and INotifyPropertyChanged.  A dictionary of members is provides through the dictionary interface, and property changed events are fired through the property changed interface.  The only way to really leverage the power of ExpandoObject is with the dynamic keyword/type, which skips compile-time checking.  Method and property calls are not shown in intellisense.  You don’t know if your code will execute property until run-time.  So to access the above mentioned interfaces, the ExpandoObject’s dynamic reference must be cast to the interface type.

Here is some very simple, sample code that illustrates the concepts discussed (runs in Visual Studio 2010 / .Net 4.0 Beta 2):


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;

namespace DynamcMethodExample
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic person = new ExpandoObject();
            person.Name = "John";
            person.Gender = 'm';
            person.Age = 10;

            Console.WriteLine(person);
            Console.WriteLine(person.Name);
            Console.WriteLine(person.Gender);
            Console.WriteLine(person.Age);
            Console.ReadKey();

            person.MakeTacos = (Func<string>)(() => "Tacos are ready!");
            Console.WriteLine(person.MakeTacos());
            Console.ReadKey();

            ((INotifyPropertyChanged)person).PropertyChanged += (s, e) =>
                {
                    IDictionary<string, object> personAsDictionary = (IDictionary<string, object>)person;
                    Console.WriteLine("Property {0} changed to {1}.", e.PropertyName, personAsDictionary[e.PropertyName]);
                };

            person.Name = "Jane";
            person.Gender = 'f';
            person.Age = 11;
            Console.ReadKey();

        }
    }
}
No TweetBacks yet. (Be the first to Tweet this post)
Advertisement

Leave a Reply

You must be logged in to post a comment.