Things I didn’t know about expando objects

I found out two inter­est­ing things about the ExpandoOb­ject class intro­duced in C# 4 this bank hol­i­day week­end:

1. you can spec­i­fy cus­tom events on them

2. it imple­ments the INo­ti­fyProp­er­ty­Changed inter­face

Here are some quick demos to show you how to use these fea­tures:

Cus­tom Events

To add a cus­tom event is the same as adding a new prop­er­ty:

   1: // event handler

   2: expando.MyEvent = null;

   3: expando.MyEvent += new EventHandler((s, e) => Console.WriteLine("MyEvent fired"));

   4:  

   5: expando.MyEvent(expando, new EventArgs());

Gener­ic event han­dlers will work too:

   1: // generic event handler

   2: expando.MyGenericEvent = null;

   3: expando.MyGenericEvent += new EventHandler<MyEventArgs>((s, e) => Console.WriteLine(e.Message));

   4:  

   5: expando.MyGenericEvent(expando, new MyEventArgs("Generic event fired"));

Because we’ve ini­tial­ize the events with null, we’ll get a run­time excep­tion if we try to invoke the event before it’s sub­scribed to (which is the same as nor­mal cus­tom events). So instead, we can use the same pat­tern I men­tioned here, and ini­tial­ize the cus­tom events with an event han­dler that does noth­ing:

   1: expando.MyOtherEvent = new EventHandler((s, e) => { });

   2:  

   3: // now you don't have to check if MyOtherEvent is null before invoking it

   4: expando.MyOtherEvent(expando, new EventArgs());

INo­ti­fyProp­er­ty­Changed

You should be famil­iar with the INo­ti­fyProp­er­ty­Changed inter­face already as it’s pret­ty damn impor­tant when it comes to data-bind­ing in UI tech­nolo­gies such as WPF and Sil­verlight. So hav­ing a dynam­ic object you can eas­i­ly bind with can help save you plen­ty of time and effort as any­one who’s ever had to write code to imple­ment the inter­face will tell you!

   1: dynamic expando = new ExpandoObject();

   2:  

   3: (expando as INotifyPropertyChanged).PropertyChanged += 

   4:     new PropertyChangedEventHandler(

   5:         (s, e) => Console.WriteLine("[{0}] was changed", e.PropertyName));

   6:  

   7: // event fired

   8: expando.MyProperty = "hello";

   9:  

  10: // event fired

  11: expando.MyProperty = "world";

  12:  

  13: // event fired

  14: (expando as IDictionary<string, object>).Remove("MyProperty");

As you can see from the code snip­pet above, the Prop­er­ty­Changed event is fired when­ev­er a prop­er­ty is added, removed or changed.

It’s also worth not­ing that there is anoth­er dynam­ic class that was intro­duced along­side the ExpandoOb­ject – the Dynam­i­cOb­ject class, which offers you more gran­u­lar con­trol of what hap­pens when some­one tries to access/update a dynam­i­cal­ly defined prop­er­ty or method.

Whilst the Dynam­i­cOb­ject class doesn’t imple­ment the INo­ti­fiyProp­er­ty­Changed inter­face itself,it is pos­si­ble for you to extend it to imple­ment the inter­face your­self, as described by this MSDN mag­a­zine arti­cle.