For my blazor library which is a modification of this awesome library I have to convert an ExpandoObject
into a Dictionary<string, object>
since ExpandoObject
s aren't serialized properly in the newest preview versions of dotnet-core. See my question related to this for more details.
My current approach goes as follows:
private static Dictionary<string, object> ConvertDynamicToDictonary(IDictionary<string, object> value)
{
return value.ToDictionary(
p => p.Key,
p =>
{
// if it's another IDict (might be a ExpandoObject or could also be an actual Dict containing ExpandoObjects) just go through it recursively
if (p.Value is IDictionary<string, object> dict)
{
return ConvertDynamicToDictonary(dict);
}
// if it's an IEnumerable, it might have ExpandoObjects inside, so check for that
if (p.Value is IEnumerable<object> list)
{
if (list.Any(o => o is ExpandoObject))
{
// if it does contain ExpandoObjects, take all of those and also go through them recursively
return list
.Where(o => o is ExpandoObject)
.Select(o => ConvertDynamicToDictonary((ExpandoObject)o));
}
}
// neither an IDict nor an IEnumerable -> it's probably fine to just return the value it has
return p.Value;
}
);
}
This works fine but I'm not sure about the IEnumerable
part. If I omit the list.Any
check it still works fine. New version (only write the IEnumerable
part changed):
// if it's an IEnumerable, it might have ExpandoObjects inside, so check for that
if (p.Value is IEnumerable<object> list)
{
// take all ExpandoObjects and go through them recursively
return list
.Where(o => o is ExpandoObject)
.Select(o => ConvertDynamicToDictonary((ExpandoObject)o));
}
I have also tried using IEnumerable<ExpandoObject>
instead of just IEnumerable<object>
to see if that would work and maybe be cleaner and I can confirm that that does not work (throws error).
What I would like to know now is, if it's a good idea to omit the Any
check and which option is more performant (and why) and/or cleaner.
Also please mention every small thing that bugs you, I always want to make it as perfect as possible :)
I first wanted to post this on StackOverflow but I think it fits better on here - correct me if I'm wrong.
EDIT 0:
This function is only called from inside the library and already marked private static
. I simply forgot to put that the first time, this is now corrected.
This answer suggests changing it into a extension method. Would this still be the "correct" way of doing it, now that it's clear that the method is not supposed to be called outside of the library itself?