Sup­pose you have an array of num­bers, say, [1, 3, 5, 7, 9, …], and you want to pair each ele­ment up with its neigh­bour in the array, e.g. [[1, 3], [3, 5], [5, 7], [7, 9], …].

Sure, you can iter­ate through the indices of the ele­ments and recur­sively grab the ele­ment at an index and its neighbour:

   1: // an array of odd numbers

   2: var arr = new[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };

   3:  

   4: // standard imperative way, iterate through the indices and grab

   5: // the elements from the arrays

   6: var arrPairs = new List<int[]>();

   7: for (var i = 0; i < arr.Length - 1; i++)

   8: {

   9:     arrPairs.Add(new[] { arr[i], arr[i+1] });

  10: }

OR, you can use LINQ and the Zip method added in .Net 4 and do this instead:

   1: var arrPairsLinq = arr.Skip(1).Zip(arr, (second, first) => new[] { first, second }).ToArray();

A much more ele­gant solu­tion, no? ;-)

Share

In C#, it’s pos­si­ble to com­bine two del­e­gates, A and B to cre­ate a new mul­ti­cast del­e­gate, C:

image image 

When the mul­ti­cast del­e­gate is exe­cuted, the com­bined del­e­gates are exe­cuted in order as you can see from the exam­ple above. But before you can start mix and match­ing your del­e­gates like a kid in a candy store, there is how­ever, the small mat­ter of hav­ing to keep the CLR happy. You see, only del­e­gates of the same type can be com­bined, but and this is a BIG but, it is a run­time require­ment that is not in line with the covari­ance sup­port in C# 4.

For instance, this is legal in C# 4:

image

As far as the com­piler is con­cerned this is fine, and it builds and runs, but when you try to invoke the mul­ti­cast del­e­gate you will get a run­time excep­tion warn­ing you that the del­e­gates must be of the same type..

Share

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

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