Using DynamicObject and ExpandoObject

by Bipin Joshi

The C# language now supports dynamic features through Dynamic Language Runtime (DLR). Part of these features include dynamic types, DynamicObject class and ExpandoObject class. This articles explains these features and provides examples illustrating how these features are used.


C# is primarily a statically typed language. That means the compiler needs to know in advance about the data type of a variable. In the absence of this information, the compiler will throw a compilation error and will refuse to compile the code. In spite of the advantages offered by the statically typed languages, dynamic languages have their own place in application development. For example, most of the web sites developed today make use of JavaScript in some way or the other. Languages such as Python and Ruby are also popular amongst developers. The C# language now supports dynamic features through Dynamic Language Runtime (DLR). Part of these features include dynamic types, DynamicObject Class and ExpandoObject Class. This article explains these features and provides examples illustrating how these features are used.

DLR functionality in .NET 4.0 is encapsulated in the System.Dynamic namespace. Ensure that in the example that follows you have imported this namespace in the class files.

Understanding the Dynamic Data Type

The C# compiler expects that you clearly specify the data type of a variable before you compile the code. In other words it enforces compile time type checking on your code. Though this works great for most of cases, at times you may want to bypass this compile time checking. Consider for example, that you wish to execute JavaScript stored in an external file and you want to exchange variables between your C# code and JavaScript code. In such cases, your C# code cannot detect the data types used in the script at compile time and you must skip the type checking. Considering such needs C# introduced the dynamic type. A dynamic type allows you to skip compile time type checking. Only at runtime when the code is actually executed, errors (if any) will be generated.

In order to understand how the dynamic type works, let's develop a simple Console Application and use dynamic variables. Begin by creating a new Console Application and then add the following code in the Main() method.

static void Main(string[] args)
    dynamic d;

    d = 100;
    Console.WriteLine(d + " - " + d.GetType());

    d = "Hello World!";
    Console.WriteLine(d + " - " + d.GetType());


The above code declares a variable (d) of type dynamic. The variable is then assigned an integer value (100) and the data type is outputted on the console window. Next, the same variable d is now assigned a string value and again its data type is outputted. The following figure shows a sample run of the application.

Sample run of the Console application
Figure 1: Sample run of the Console application

Notice the above figure carefully. The first line shows that d is an integer type whereas the second line shows that d is a string. This means that a dynamic variable can change its data type at runtime. If you try to perform invalid operations on the data (using string manipulation functions on an integer or using mathematical functions on a string for example) then an error will be generated at runtime.

Difference Between var and Dynamic Types

At first glance you may find the dynamic type is the same as variables of the var type. However, they are not the same. When you use a var keyword (say in a LINQ query) the data type is detected in a delayed fashion but once a variable is assigned a value the data type is fixed. It cannot be changed later. In the case of dynamic types, however, the data type can change multiple times during the execution of the application. As long as the operation under consideration is valid the runtime won't have any problem in dealing with a dynamic variable. Just to explain this difference, consider the following fragment of code:

 string[] strMonths = { "Jan", "Feb", "Mar"};
int[] numMonths = { 1, 2, 3 };

//OK because it is first assignment
var varMonths = from m in strMonths
                select m;

//ERROR because varMonths is already a collection of strings
//and now cannot take integers
varMonths = from m in numMonths
            select m;

As you can see above, var cannot change its data type once assigned whereas dynamic variable can change its data type as we did in the previous example.

Understanding Dynamic Objects

Normally when you wish to use some object in your code, you first need to create a class and write properties and methods in it. You can then create objects of that class, set their properties and invoke methods on them. At times, however, you may want to create objects and set their properties dynamically. That means you won't have a class against which the compiler can validate your property assignments or method calls. Why is something like this ever needed? Consider that you are exchanging data between an external script and C#. Now your C# code won't be aware of the objects exposed by the script at compile time for obvious reasons. So in your C# code you will be assigning properties and invoking methods without knowing if they really exist. Errors, if any, will be raised only at runtime.

One example of such a dynamic object can be found in ASP.NET MVC 3. Consider the following piece of code written in a controller class:

ViewBag.StatusMessage = "Data saved successfully!";
ViewBag.StatusCode = "100";
ViewBag.LogDate = DateTime.Now;

ASP.NET MVC 3 provides a ViewBag object that allows you to store arbitrary values that you wish to pass to the View. As illustrated in the above example, you simply set properties on the ViewBag object as if they are coded in the ViewBag object itself. In reality, ViewBag doesn't contain any property definitions for StatusMessage, StatusCode and LogDate (these names are developer defined and you can use any valid name there). In other words, you added properties dynamically to the ViewBag object.

The System.Dynamic namespaces provides two classes that allow you to create your own dynamic objects. They are - DynamicObject and ExpandoObject. both of which implement the IDynamicMetaObjectProvider interface. The IDynamicMetaObjectProvider interface allows you to bind operations to the underlying object at runtime. In the following sections you will learn how to make use of DynamicObject class as well as ExpandoObject class.

DynamicObject Class

In order to create your own dynamic object using DynamicObject class you need to inherit it from DynamicObject and override three methods, viz. TryGetMember, TrySetMember and TryInvokeMember. The first two methods allow you to get and set dynamic properties whereas the last method allows you to invoke method calls on the dynamic object. In order to understand how these three methods can be used let's create a dynamic object - Employee.

Add a new class to the Console Application you created earlier and key the following code into it:

public class Employee : DynamicObject

    Dictionary<string, object> properties = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
        if (properties.ContainsKey(binder.Name))
            result = properties[binder.Name];
            return true;
            result = "Invalid Property!";
            return false;

    public override bool TrySetMember(SetMemberBinder binder, object value)
        properties[binder.Name] = value;
        return true;

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        dynamic method = properties[binder.Name];
        result = method(args[0].ToString(), args[1].ToString());
        return true;

As you can see the Employee class inherits from the DynamicObject base class and then overrides the TryGetMember, TrySetMember and TryInvokeMember methods. The TryGetMember() method returns a boolean value indicating whether the operation was successful or not. The actual property value is retrieved via the results output parameter. The property values are stored in a dictionary (properties). You then check whether the property whose value is to be retrieved (binder.Name) exists in the dictionary. Accordingly, result output parameter is set and true / false is returned.

The TrySetMember() method simply stores a property and its value in the dictionary and returns true. If you wish to restrict property names or values based on certain criteria you will add that logic here and return true / false accordingly. In our case we don't have any such restriction and the code returns true.

The TryInvokeMember() method retrieves a reference to an anonymous function (this will be clear in a moment) and invokes that function by passing the required parameters.

Once you complete the Employee class, modify the Main() method to include the following lines of code:

d = new Employee();
d.FirstName = "Tom";
d.LastName = "Jerry";
d.BirthDate = new DateTime(1960, 12, 01);

Func<string, string, string> method = (a, b) => a + " " + b;

d.GetData = method;
Console.WriteLine(d.FirstName + " " + d.LastName + "..." + d.GetData("Tom", "Jerry") + " - " + d.GetType());

The above code assigns a new instance of Employee class to the dynamic variable (d). It then sets three properties on the dynamic object viz. FirstName, LastName and BirthDate. Notice that Employee class nowhere defines these properties and you are setting them dynamically. The code then creates an anonymous method that simply concatenates and returns the two parameters passed to it. The GetData dynamic method is then set to point to this anonymous method. Finally, FirstName, LastName values are outputted along with a call to GetData() dynamic method. The following figure shows a sample run of the above code:

Sample run a new instance of Employee class to the dynamic
Figure 2: Sample run a new instance of Employee class to the dynamic variable

ExpandoObject Class

In the case of the DynamicObject class, you need to do more work by inheriting and overriding certain methods. In the process you get more control on how the resultant dynamic object should behave. The ExpandoObject class is a sealed class, which means you cannot inherit it further. It provides a simpler implementation of a dynamic object ready for you to consume in your applications without much work. The same code that we used in the preceding example can be written using ExpandoObject as follows:

d = new ExpandoObject();
d.FirstName = "Tom";
d.LastName = "Jerry";
d.BirthDate = new DateTime(1960, 12, 01);

Func<string, string, string> method2 = (a, b) => a + " " + b;

d.GetData = method2;
Console.WriteLine(d.FirstName + " " + d.LastName + "..." + d.GetData("Tom", "Jerry") + " - " + d.GetType());

Notice that the above code creates an instance of ExpandoObject and sets properties on it as before.

An instance of ExpandoObject with properties
Figure 3: An instance of ExpandoObject with properties


The dynamic type allows you to write code that bypasses compile time type checking. A variable of dynamic type can point to different types at runtime. You can create your own dynamic objects using DynamicObject and ExpandoObject classes. In order to use the DynamicObject class you need to create a class that inherits from DynamicObject class and then override TryGetMember, TrySetMember and TryInvokeMember methods. This approach gives you precise control on the properties and methods the dynamic object can have. On the other hand ExpandoObject provides a simple ready to use implementation of a dynamic object. Using these features. you can create dynamic objects that allow you to add properties and methods to them dynamically.

This article was originally published on Monday Jul 11th 2011
Mobile Site | Full Site