Sunday, June 10, 2012

What are the true benefits of ExpandoObject?


The ExpandoObject class being added to .NET 4 allows you to arbitrarily set properties onto an object at runtime.



Are there any advantages to this over using a Dictionary<string,object> , or really even a Hashtable ? As far as I can tell, this is nothing but a hash table that you can access with slightly more succinct syntax.



For example, why is this:




dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);



Really better, or substantially different, than:




var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);



What real advantages are gained by using ExpandoObject instead of just using an arbitrary dictionary type, other than not being obvious that you're using a type that's going to be determined at runtime.


Source: Tips4all

6 comments:

  1. Since I wrote the MSDN article you are referring to, I guess I have to answer this one.

    First, I anticipated this question and that's why I wrote a blog post that shows a more or less real use case for ExpandoObject: Dynamic in C# 4.0: Introducing the ExpandoObject.

    Shortly, ExpandoObject can help you create complex hierarchical objects. For example, imagine that you have a dictionary within a dictionary:

    Dictionary<String, object> dict = new Dictionary<string, object>();
    Dictionary<String, object> address = new Dictionary<string,object>();
    dict["Address"] = address;
    address["State"] = "WA";
    Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);


    The deeper is the hierarchy, the uglier is the code. With ExpandoObject it stays elegant and readable.

    dynamic expando = new ExpandoObject();
    expando.Address = new ExpandoObject();
    expando.Address.State = "WA";
    Console.WriteLine(expando.Address.State);


    Second, as it was already pointed out, ExpandoObject implements INotifyPropertyChanged interface which gives you more control over properties than a dictionary.

    Finally, you can add events to ExpandoObject like here:

    class Program
    {

    static void Main(string[] args)
    {
    dynamic d = new ExpandoObject();

    // Initialize the event to null (meaning no handlers)
    d.MyEvent = null;

    // Add some handlers
    d.MyEvent += new EventHandler(OnMyEvent);
    d.MyEvent += new EventHandler(OnMyEvent2);

    // Fire the event
    EventHandler e = d.MyEvent;

    if (e != null)
    {
    e(d, new EventArgs());
    }

    // We could also fire it with...
    // d.MyEvent(d, new EventArgs());

    // ...if we knew for sure that the event is non-null.
    }

    static void OnMyEvent(object sender, EventArgs e)
    {
    Console.WriteLine("OnMyEvent fired by: {0}", sender);
    }

    static void OnMyEvent2(object sender, EventArgs e)
    {
    Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
    }
    }

    ReplyDelete
  2. One advantage is for binding scenarios. Data grids and property grids will pick up the dynamic properties via the TypeDescriptor system. In addition, WPF data binding will understand dynamic properties, so WPF controls can bind to an ExpandoObject more readily than a dictionary.

    Interoperability with dynamic languages, which will be expecting DLR properties rather than dictionary entries, may also be a consideration in some scenarios.

    ReplyDelete
  3. It's all about programmer convenience. I can imagine writing quick and dirty programs with this object.

    ReplyDelete
  4. Interop with other languages founded on the DLR is #1 reason I can think of. You can't pass them a Dictionary<string, object> as it's not an IDynamicMetaObjectProvider. Another added benefit is that it implements INotifyPropertyChanged which means in the databinding world of WPF it also has added benefits beyond what Dictionary<K,V> can provide you.

    ReplyDelete
  5. I think it will have a syntactic benefit, since you'll no longer be "faking" dynamically added properties by using a dictionary.

    That, and interop with dynamic languages I would think.

    ReplyDelete
  6. The real benefit for me is the totally effortless data binding from XAML:

    public dynamic SomeData { get; set; }


    ...

    SomeData.WhatEver = "Yo Man!";


    ...

    <TextBlock Text="{Binding SomeData.WhatEver}" />

    ReplyDelete