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

1. you can spec­ify cus­tom events on them

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

Here are some quick demos to show you how to use these features:

Cus­tom Events

To add a cus­tom event is the same as adding a new property:

   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());

Generic 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 nothing:

   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 pretty damn impor­tant when it comes to data-binding in UI tech­nolo­gies such as WPF and Sil­verlight. So hav­ing a dynamic object you can eas­ily bind with can help save you plenty 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­ever a prop­erty is added, removed or changed.

It’s also worth not­ing that there is another dynamic 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­cally defined prop­erty 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 article.

Share

In C#, when you have to work with JSON data you’re usu­ally rep­re­sented with two choices – Dat­a­Con­trac­tJ­son­Se­ri­al­izer or JavaScript­Se­ri­al­izer. There are other pop­u­lar third-party libraries out there, such as the pop­u­lar Json.Net project, but for the rest of this blog let’s just focus on the two built-in JSON seri­al­iz­ers and see how they differ.

Dat­a­Con­tracts

With­out doubt the biggest dif­fer­ence between the two is that Dat­a­Con­trac­tJ­son­Se­ri­al­izer only works with types dec­o­rated with the Dat­a­Con­tract attribute, but JavaScript­Se­ri­al­izer can work with any object.

This makes per­fect sense as the pri­mary pur­pose of the Dat­a­Con­trac­tJ­son­Se­ri­al­izer is to be used with WCF, and just as its name sug­gests, it’s a JSON seri­al­izer for Dat­a­Con­tract types.

Anony­mous Types

One inter­est­ing side effect of the above is that you can’t use Dat­a­Con­trac­tJ­son­Se­ri­al­izer with anony­mous types.

On the other hand, with the JavaScript­Se­ri­al­izer at least you can eas­ily seri­al­ize an instance of an anony­mous type:

   1: var jsSerializer = new JavaScriptSerializer();

   2:  

   3: // define an anonymous type

   4: var anonymous = new { Id = Guid.NewGuid(), Name = "Yan", Age = 29 };

   5:  

   6: // this writes:

   7: // {"Id":"2edebefb-2585-438c-bbc3-939e7688f630","Name":"Yan","Age":29}

   8: Console.WriteLine(jsSerializer.Serialize(anonymous));

Unfor­tu­nately you won’t be able to dese­ri­al­ize the JSON string back into an anony­mous type as all the avail­able dese­ri­al­ize meth­ods requires a type which has a para­me­ter­less constructor.

Dic­tio­nar­ies

Another main func­tional dif­fer­ence between these two seri­al­iz­ers is how they deal with dictionaries.

Take this sim­ple dic­tio­nary for instance:

   1: var dictionary = new Dictionary<string, object>();

   2: dictionary.Add("Id", Guid.NewGuid());

   3: dictionary.Add("Name", "Yan");

   4: dictionary.Add("Age", 29);

The Dat­a­Con­trac­tJ­son­Se­ri­al­izer seri­al­izes dic­tio­nar­ies as an array of Key­Val­ue­Pair objects:

[{“Key”:“Id”,“Value”:“35285943-32d0-45d9-ada6-eb570f757d85”},{“Key”:“Name”,“Value”:“Yan”},{“Key”:“Age”,“Value”:29}]

whereas the JavaScript­Se­ri­al­izer seri­al­izes dic­tio­nar­ies in a much more ‘JSON’ way:

{“Id”:“35285943-32d0-45d9-ada6-eb570f757d85”,“Name”:“Yan”,“Age”:29}

This sub­tle dif­fer­ent might seem triv­ial at first, but it can make a huge dif­fer­ence when you’re deal­ing with data that are orig­i­nated from a non-.Net lan­guage. A per­fect exam­ple came cou­ple of days ago when we were test­ing out the Face­book graph API and one of the JSON responses we came across was a dic­tio­nary whose keys were numeric IDs like this:

{“1652438520054”:{“id”:“1652438520054”, …}}

In cases like this, you sim­ply won’t be able to dese­ri­al­ize this JSON using the Dat­a­Con­trac­tJ­son­Se­ri­al­izer!

Share

As many oth­ers have shown, the new ExpandoOb­ject intro­duced in C# 4 can be pretty use­ful in some scenarios.

How­ever, on the odd occa­sion when you want to con­vert an ExpandoOb­ject to a sta­tic type you have defined you can be for­given for feel­ing a lit­tle lost as there are no well doc­u­mented ways to do that. At least that’s how I felt, until I found out about the Con­vert­To­Type meth­ods on the JavaScript­Se­ri­al­izer!

JavaScript­Se­ri­al­izer

The JavaScript­Se­ri­al­izer, like the Dat­a­Con­trac­tJ­son­Se­ri­al­izer class, lets you seri­al­ize and dese­ri­al­ize objects to and from JSON string. But unlike the Dat­a­Con­trac­tJ­son­Se­ri­al­izer class, you are not con­fined to work­ing with types that are marked with the Dat­a­Con­tract attribute.

One of the dese­ri­al­iza­tion meth­ods on the JavaScript­Se­ri­al­izer class – Dese­ri­al­izeOb­ject – lets you a JSON string to an object graph, i.e. a Dictionary<string, object> object where the key is the name of the prop­erty and the value is the prop­erty value. And you can use one of the over­loaded Con­vert­To­Type meth­ods to con­vert this dic­tio­nary to a sta­tic type of your choice, pro­vided that the type has a para­me­ter­less con­struc­tor (which unfor­tu­nately, means you won’t be able to con­vert an ExpandoOb­ject to an anony­mous type).

ExpandoOb­ject as IDictionary<string, object>

Why is this impor­tant? It’s because the ExpandoOb­ject imple­ments the IDictionary<string, object> inter­face and there­fore can be used with the Con­vert­To­Type methods!

Here’s what you do:

   1: // first you need to instantiate the serializer

   2: var jsSerializer = new JavaScriptSerializer();

   3:

   4: // get an expando object and convert it to an instance of MyClass

   5: var expando = GetExpandoObject();

   6: var obj = jsSerializer.ConvertToType<MyClass>(expando);

   7:

   8: Console.WriteLine(obj.Id);      // 0db9d9a6-8c7e-4bea-82a8-4d5641c7c0de

   9: Console.WriteLine(obj.Name);    // Yan

  10: Console.WriteLine(obj.Age);     // 29

  11:

  12: ...

  13:

  14: public ExpandoObject GetExpandoObject()

  15: {

  16:     dynamic expando = new ExpandoObject();

  17:     expando.Id = Guid.NewGuid();

  18:     expando.Name = "Yan";

  19:     expando.Age = 29;

  20:

  21:     return expando;

  22: }

  23:

  24: public class MyClass

  25: {

  26:     public Guid Id { get; set; }

  27:

  28:     public string Name { get; set; }

  29:

  30:     public int Age { get; set; }

  31: }

Pretty cool, eh? ;-)

But what if the shape of the expando object doesn’t match your type? E.g. there are prop­er­ties defined on MyClass but not on the expando object, or vice versa, or both? Well, it’s smart enough to work that out itself and only set the prop­er­ties which it is able to set:

   1: // same as before

   2:

   3: Console.WriteLine(obj.Id);          // 0db9d9a6-8c7e-4bea-82a8-4d5641c7c0de

   4: Console.WriteLine(obj.Name);        // null

   5: Console.WriteLine(obj.Age);         // 29

   6: Console.WriteLine(obj.NickName);    // null

   7:

   8: ...

   9:

  10: public ExpandoObject GetExpandoObject()

  11: {

  12:     dynamic expando = new ExpandoObject();

  13:     expando.Id = Guid.NewGuid();

  14:     expando.Name = "Yan";

  15:     expando.Age = 29;

  16:     expando.Wife = "Yinan";    // not defined on MyClass

  17:

  18:     return expando;

  19: }

  20:

  21: public class MyClass

  22: {

  23:     public Guid Id { get; set; }

  24:

  25:     public string Name { get; private set; } // non-public setter

  26:

  27:     public int Age { get; set; }

  28:

  29:     public string NickName { get; set; } // not defined on ExpandoObject

  30: }

Share

As you know, the ExpandoOb­ject class imple­ments the IDictionary<string, object> inter­face, so if you have an ExpandoOb­ject you can eas­ily cast it to an IDictionary<string, object> but there’s no built-in way to eas­ily do the reverse.

Luck­ily, I came across a very use­ful exten­sion method today which con­verts an IDictionary<string, object> into an ExpandoOb­ject, which you can then use dynam­i­cally in your code, sweet! :-)

With some small mod­i­fi­ca­tions, here’s the code I ended up with, with some com­ments thrown in for good measures:

   1: /// <summary>

   2: /// Extension method that turns a dictionary of string and object to an ExpandoObject

   3: /// </summary>

   4: public static ExpandoObject ToExpando(this IDictionary<string, object> dictionary)

   5: {

   6:     var expando = new ExpandoObject();

   7:     var expandoDic = (IDictionary<string, object>)expando;

   8:  

   9:     // go through the items in the dictionary and copy over the key value pairs)

  10:     foreach (var kvp in dictionary)

  11:     {

  12:         // if the value can also be turned into an ExpandoObject, then do it!

  13:         if (kvp.Value is IDictionary<string, object>)

  14:         {

  15:             var expandoValue = ((IDictionary<string, object>)kvp.Value).ToExpando();

  16:             expandoDic.Add(kvp.Key, expandoValue);

  17:         }

  18:         else if (kvp.Value is ICollection)

  19:         {

  20:             // iterate through the collection and convert any strin-object dictionaries

  21:             // along the way into expando objects

  22:             var itemList = new List<object>();

  23:             foreach (var item in (ICollection)kvp.Value)

  24:             {

  25:                 if (item is IDictionary<string, object>)

  26:                 {

  27:                     var expandoItem = ((IDictionary<string, object>) item).ToExpando();

  28:                     itemList.Add(expandoItem);

  29:                 }

  30:                 else

  31:                 {

  32:                     itemList.Add(item);

  33:                 }

  34:             }

  35:  

  36:             expandoDic.Add(kvp.Key, itemList);

  37:         }

  38:         else

  39:         {

  40:             expandoDic.Add(kvp);

  41:         }

  42:     }

  43:  

  44:     return expando;

  45: }

Enjoy!

Share

Anony­mous types are use­ful, espe­cially in LINQ queries where you often want to iter­ate through an array of items and project them into some arbi­trar­ily shaped objects that are lit­tle more than sim­ple data con­tain­ers, using anony­mous types save you the has­sle of hav­ing to first declare those types which you will sim­ply throw away afterwards.

One thing you can’t eas­ily do with anony­mous types how­ever, is to return them from the method it’s declared in and use them else­where. Sure, you can return an instance of an anony­mous type as object, but that doesn’t make it any eas­ier to work with them as you don’t have access to any of the prop­er­ties on the anony­mous type. So what can you do in those cases?

Cast By Example

This is a nifty tech­nique which can deals with the above prob­lem, and all you need is a sim­ple method like this:

   1: public static T CastByExample<T>(this object o, T example) 

   2: { 

   3:     return (T) o; 

   4: }

You can then take an instance of an anony­mous type and cast it back to its orig­i­nal shape:

   1: static object GetAnonymousType() 

   2: { 

   3:     return new { FirstName = "Yan", Surname = "Cui", Age = 29 };

   4: }

   5:  

   6: ...

   7:  

   8: object o = GetAnonymousType();

   9:  

  10: // get the original anonymous type back again 

  11: var o2 = o.CastByExample(new { FirstName = "", Surname = "", Age = 0 });

  12:  

  13: // you can now use the properties on the original anonymous type freely

  14: Console.WriteLine(o2.FirstName);

This works, but only if the exam­ple is the exact shape as the orig­i­nal, oth­er­wise you’ll get an Invalid­Cas­tEx­cep­tion:

   1: // throws InvalidCastException

   2: // Unable to cast object of type '<>f__AnonymousType0`3[System.String,System.String,System.Int32]'

   3: // to type '<>f__AnonymousType1`2[System.String,System.String]'.

   4: var o2 = o.CastByExample(new { FirstName = "", Surname = "" });

Dynamic Pro­gram­ming

An alter­na­tive to using the Cast By Exam­ple tech­nique is to take advan­tage of the dynamic key­word intro­duced in C# 4, whilst this approach makes every­thing soooo easy, the trade off is that you lose intel­lisense support.

   1: // simply cast the returned object as a dynamic and off you go!

   2: var o = (dynamic)GetAnonymousType();

   3:  

   4: Console.WriteLine(o.FirstName);

Of course, if you try to use a prop­erty that isn’t defined on the anony­mous type then you’ll get an excep­tion at run­time, specif­i­cally the Run­time­BinderEx­cep­tion.

Part­ing Thoughts..

Both tech­niques can help make life eas­ier if on the rare occa­sion you need to return an anony­mous type from your method, but if you find your­self doing that fre­quently in your code then it’s prob­a­bly best to take a step back and rethink your over­all archi­tec­ture. Anony­mous types are con­fined to meth­ods by design, and for a good rea­son! If you’ve struc­tured your code cor­rectly fol­low­ing good OOP design prin­ci­ples then there should be very lit­tle need to ‘hack’ your way through using these tech­niques! So as a part­ing shot, please use these tech­niques with cau­tion and only when absolutely necessary!

Share