Building C# objects dynamically

This is an excerpt from C# 6.0 Cookbook, by Jay Hilyard and Stephen Teilhet. The book offers more than 150 code recipes to common and not-so-common problems that C# programmers face every day. In it, you’ll find recipes on asynchronous methods, dynamic objects, enhanced error handling, the Rosyln compiler, and more.

Problem

You want to be able to build up an object to work with on the fly at runtime.

Solution

Use ExpandoObject to create an object that you can add properties, methods, and events to and be able to data bind to in a user interface.

We can use ExpandoObject to create an initial object to hold the Name and current Country of a person.

Once we have added properties directly, we can also add properties to our object in a more dynamic fashion using the AddProperty method we have provided for you. One example of why you might do this is to add properties to your object from another source of data. We will add the Language property.

Now we can also define and add events to the ExpandoObject using the Action<> generic type. We will add two events, LanguageChanged and CountryChanged. LanguageChanged will be added after defining the eventHandler variable to hold the Action<object,EventArgs> and CountryChanged we will add directly as an inline anonymous method. CountryChanged looks at the Country that changed and invokes the LanguageChanged event with the proper Language for the Country. (Note that LanguageChanged is also an anonymous method but sometimes it can make for cleaner code to have a variable for these).

Finally, ExpandoObject supports INotifyPropertyChanged which is the foundation of data binding to properties in .NET. We hook up the event handler and when the Country property is changed, we fire the CountryChanged event.

Discussion

ExpandoObject allows you to write code that is more readable than typical reflection code with GetProperty(“Field”) syntax. It can be useful when dealing with XML or JSON for quickly setting up a type to program against instead of always having to create data transfer objects. The ability for ExpandoObject to support data binding through INotifyPropertyChanged is a huge win for anyone using WPF, MVC, or any other binding framework in .NET as it allows you to use these “objects on the fly” as well as other statically typed classes.

Since ExpandoObject can take delegates as members, this allows us to attach methods and events to these dynamic types while the code looks like you are addressing a static type.

For both AddEvent and AddProperty, you might be asking why didn’t we use extension methods for AddProperty and AddEvent? They both could hang off of ExpandoObject and make the syntax even cleaner, right? Unfortunately, that is not possible as extension methods work by the compiler doing a search on all classes that might be a match for the extended class. This means that the DLR would have to know all of this information at runtime as well (since ExpandoObject is handled by the DLR) and currently all of that information is not encoded into the call site for the class and methods.

The event argument classes for the LanguageChanged and CountryChanged events are listed here:

Jay Hilyard has been developing applications for the Windows platform for over 20 years, including .NET. He’s published numerous articles in MSDN Magazine. Jay currently works at Newmarket, an Amadeus company.

Stephen Teilhet started working with the pre-alpha version of the .NET platform and has been using it ever since. At IBM, he works as the lead security researcher on their static source code security analysis tool, which is used to find vulnerabilities in many different languages, including C# and Visual Basic.