Converting ExpandObject

How ExpandObject can be converted to IEnumerable and a Dictionary

Home DailyDrop

Daily Knowledge Drop

The ExpandoObject class implements IEnumberable and IDictionary - this means its fields can be iterated over, and that it can be converted to, and operated on as a Dictionary.


ExpandoObject

First some information on the ExpandoObject class - it enables one to add and deleted members of its instance at runtime.

dynamic infoObject = new ExpandoObject();
infoObject.Name = "Always Developing";
infoObject.Url = "www.alwaysdeveloping.net";

Console.WriteLine(infoObject.Name);
Console.WriteLine(infoObject.Url);

In the above example, the properties Name and Age are dynamically added at runtime. Any number of properties, of any type can dynamically be added.

The ExpandoObject can also have methods (Action and Func) added dynamically, and then invoked:

dynamic infoObject = new ExpandoObject();
infoObject.Name = "Always Developing";
infoObject.Url = "www.alwaysdeveloping.net";
infoObject.Visitors = 0;
infoObject.IncreaseVisitorCount = (Action)(() => { infoObject.Visitors++; });
infoObject.GetVisitorCount = (Func<int>)(() => { return infoObject.Visitors; });

infoObject.IncreaseVisitorCount();
infoObject.IncreaseVisitorCount();

Console.WriteLine(infoObject.GetVisitorCount());

The IncreaseVisitorCount Action and GetVisitorCount Func are dynamically added, and then invoked.

The output of the above being 2, as expected, as the IncreaseVisitorCount method is invoked twice.


IEnumerable conversion

As ExpandoObject implement IEnumberable, specifically IEnumerable<KeyValuePair<string, object?>> and can be iterated over, with a KeyValuePair<string, object?> item returned for each iteration:

dynamic infoObject = new ExpandoObject();
infoObject.Name = "Always Developing";
infoObject.Url = "www.alwaysdeveloping.net";
infoObject.Visitors = 0;
infoObject.IncreaseVisitorCount = (Action)(() => { infoObject.Visitors++; });
infoObject.GetVisitorCount = (Func<int>)(() => { return infoObject.Visitors; });

// prop is of type KeyValuePair<string, object?>
foreach (var prop in infoObject)
{
    Console.WriteLine($"Key: '{prop.Key}' with value '{prop.Value}'");
}

In the above, iterating over infoObject will return each property dynamically added to the ExpandoObject instance, including methods:

Key: 'Name' with value 'Always Developing'
Key: 'Url' with value 'www.alwaysdeveloping.net'
Key: 'Visitors' with value '2'
Key: 'IncreaseVisitorCount' with value 'System.Action'
Key: 'GetVisitorCount' with value 'System.Func`1[System.Int32]'

Dictionary conversion

ExpandoObject also implements IDictionary<string, object?>, so can directly be assigned to this type:

dynamic infoObject = new ExpandoObject();
infoObject.Name = "Always Developing";
infoObject.Url = "www.alwaysdeveloping.net";
infoObject.Visitors = 0;
infoObject.IncreaseVisitorCount = (Action)(() => { infoObject.Visitors++; });
infoObject.GetVisitorCount = (Func<int>)(() => { return infoObject.Visitors; });

// cast ExpandoObject to IDictionary<string, object?>
IDictionary<string, object?> dictionary = infoObject;
foreach (var item in dictionary)
{
    Console.WriteLine($"Key: '{item.Key}' with value '{item.Value}'");
}

The output of the above the same as the first example:

Key: 'Name' with value 'Always Developing'
Key: 'Url' with value 'www.alwaysdeveloping.net'
Key: 'Visitors' with value '2'
Key: 'IncreaseVisitorCount' with value 'System.Action'
Key: 'GetVisitorCount' with value 'System.Func`1[System.Int32]'

Casting to Dictionary allows one to check if a property/key has been added to the ExpandoObject:

IDictionary<string, object?> dictionary = infoObject;
foreach (var item in dictionary)
{
    Console.WriteLine($"Key: '{item.Key}' with value '{item.Value}'");
}

// This would result in an exception
// var value = infoObject["Name"];

// On a dictionary, this is allowed
if (dictionary.ContainsKey("Name"))
{
    Console.WriteLine(dictionary["Name"]);
}

Notes

This is a small, but useful piece of knowledge to be aware of if working with ExpandoObject as the ability to easily convert to other types opens up new operations and possibilities on the instance.


References

C# Tip: Convert ExpandoObjects to IDictionary

Daily Drop 101: 22-06-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net expandobject dictionary ienumerable