Code4IT

The place for .NET enthusiasts, Azure lovers, and backend developers

C# Tip: Convert ExpandoObjects to IDictionary

2022-05-10 2 min read CSharp Tips
Just a second! 🫷
If you are here, it means that you are a software developer. So, you know that storage, networking, and domain management have a cost .

If you want to support this blog, please ensure that you have disabled the adblocker for this site. I configured Google AdSense to show as few ADS as possible - I don't want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

Thank you for your understanding.
- Davide

In C#, ExpandoObjects are dynamically-populated objects without a predefined shape.

dynamic myObj = new ExpandoObject();
myObj.Name ="Davide";
myObj.Age = 30;

Name and Age are not part of the definition of ExpandoObject: they are two fields I added without declaring their type.

This is a dynamic object, so I can add new fields as I want. Say that I need to add my City: I can simply use

myObj.City = "Turin";

without creating any field on the ExpandoObject class.

Now: how can I retrieve all the values? Probably the best way is by converting the ExpandoObject into a Dictionary.

Create a new Dictionary

Using an IDictionary makes it easy to access the keys of the object.

If you have an ExpandoObject that will not change, you can use it to create a new IDictionary:

dynamic myObj = new ExpandoObject();
myObj.Name ="Davide";
myObj.Age = 30;


IDictionary<string, object?> dict = new Dictionary<string, object?>(myObj);

//dict.Keys: [Name, Age]

myObj.City ="Turin";

//dict.Keys: [Name, Age]

Notice that we use the ExpandoObject to create a new IDictionary. This means that after the Dictionary creation if we add a new field to the ExpandoObject, that new field will not be present in the Dictionary.

Cast to IDictionary

If you want to use an IDictionary to get the ExpandoObject keys, and you need to stay in sync with the ExpandoObject status, you just have to cast that object to an IDictionary

dynamic myObj = new ExpandoObject();
myObj.Name ="Davide";
myObj.Age = 30;

IDictionary<string, object?> dict = myObj;

//dict.Keys: [Name, Age]

myObj.City ="Turin";

//dict.Keys: [Name, Age, City]

This works because ExpandoObject implements IDictionary, so you can simply cast to IDictionary without instantiating a new object.

Here’s the class definition:

public sealed class ExpandoObject :
	IDynamicMetaObjectProvider,
	IDictionary<string, object?>,
	ICollection<KeyValuePair<string, object?>>,
	IEnumerable<KeyValuePair<string, object?>>,
	IEnumerable,
	INotifyPropertyChanged

Wrapping up

Both approaches are correct. They both create the same Dictionary, but they act differently when a new value is added to the ExpandoObject.

Can you think of any pros and cons of each approach?

Happy coding!

🐧

About the author

Davide Bellone is a Principal Backend Developer with more than 10 years of professional experience with Microsoft platforms and frameworks.

He loves learning new things and sharing these learnings with others: that’s why he writes on this blog and is involved as speaker at tech conferences.

He's a Microsoft MVP πŸ†, conference speaker (here's his Sessionize Profile) and content creator on LinkedIn.