The community is working on translating this tutorial into Ukrainian, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".
The ExpandoObject
As we saw in a previous article, we can use the dynamic keyword to hold an object where we get to define the properties, without having to define the class first. What we can't do with a dynamic object is dynamically adding properties to it after the object has been initialized. If you need this specific ability, C# comes with a solution for you: The ExpandoObject. Let's jump straight to an example, so you can see how easy it is to use:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = "New York";
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown);
You will notice that I declare the object with the dynamic type, even though I instantiate an ExpandoObject. The reason is that if the object was declared as an ExpandoObject, the compiler would check it and immediately complain about the lack of the properties that we invent for it (Name, Age and so on). We can prevent this by declaring it as a dynamic, which as we learned in the previous article, will prevent the compiler from checking for the existence of the properties we use.
A cool thing is that an ExpandoObject can of course have properties which are also ExpandoObject's, allowing you to make complex types on the fly, like in this example:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = new System.Dynamic.ExpandoObject();
user.HomeTown.Name = "New York";
user.HomeTown.ZipCode = 10001;
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]");
I simply change the HomeTown property from a string to an ExpandoObject, and then add properties to it, in this case the name and the zip code of the city. But it doesn't have to end with that - we can even add methods to the object, again on the fly, using some pretty sophisticated tricks:
user.DescribeUser = (Func<String>)(() => {
return user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]";
});
Console.WriteLine(user.DescribeUser());
Pretty neat stuff, but what IS an ExpandoObject really? It implements several interesting interfaces, but one of them is IDictionary<string, object> - this means that underneath all the syntactical sugar, your ExpandoObject is basically just a dictionary which holds object values based on string keys. That also means that iterating over an ExpandoObject is just as easy as iterating through a regular Dictionary. This is very practical:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
foreach (KeyValuePair<string, object> kvp in user)
{
Console.WriteLine(kvp.Key + ": " + kvp.Value);
}
Summary
The ExpandoObject type allows you to define objects on the fly and then add properties to it whenever you want to. Since it's basically a dynamic type, it inherits the same advantages and disadvantages as we discussed in the previous article. As a bonus though, the ExpandoObject implements the INotifyPropertyChanged interface, which you'll definitely appreciate if you're using e.g. WPF for your application.