Wednesday, May 20, 2009

Introducing System.Dynamic.ExpandoObject...

By now, those of you who have been using VS 2010 have probably noticed that you can't simply call "new dynamic()" anywhere. Why not?

The dynamic type is designed to rest upon another type. It depends on it's underlying type for member resolution, which is why the C# new features document constantly uses a fictional method "GetDynamicObject" within it's description of the dynamic type. It seems that whatever is returned from that method is what will decide which members are available.

It's almost like dynamic is nothing but a way to call members without casting to a particular type. This is great and all, but what if I want to add members?

Enter the ExpandoObject, which probably has the best name of any class in the entire framework. What does it do?

Intellisense says of the ExpandoObject:

Represents an object with members that can be dynamically added.


That's a wonderful description, and perfectly correct.

So how can this be used? Check out the following code:


dynamic x = new ExpandoObject();
x.SomeText = "This is some text";
x.Value = 30;
x.Run = new Action(() => Console.WriteLine("Running a recently added method!"));
Console.WriteLine(x.SomeText);
Console.WriteLine(x.Value);
x.Run();


Pretty cool, huh?

Keep in mind that the summary for the parameterless (the only) constructor for ExpandoObject, according to Intellisense, is the following:

Creates a new ExpandoObject without members.


Without members? I just added two! Nice addition to the language indeed!

Another cool thing you can do with ExpandoObject is prevent closures when defining the methods. This, in my opinion, makes for a very... well... dynamic object. Check out the following code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
dynamic x = new ExpandoObject();
x.Value = 30;
x.ShowValue = new Action(() => Console.WriteLine(x.Value));
ProcessDynamic(x);
}
static void ProcessDynamic(dynamic d)
{
d.Value = 2;
d.ShowValue();
}
}
}


What do you think this code will produce? At first glance, I figured that it would print out "30" because it would have closed over the actual value in x.Value, but it doesn't. Instead, it keeps a reference to the variable, even when passing into another scope, such as when "x" goes out of scope, and into the other method, called ProcessDynamic. The output is 2.

I'm so glad to see this added to the .NET Framework! Use it. Don't abuse it.