Well, there are a few cons and pros of using Dictionary here (mostly pros)
Pros:
- It doesn't require additional logics
- You're using benefits of C# as strongly typed language and type check exceptions are thrown at compile time
- It is efficient
Cons:
- It requires to write more code and is less flexible
If you have tons of calls where you pass dictionaries and performance is not your main concern you might want to create another overload for your method that accepts anonymous object, checks it, and creates a dictionary out of it:
public void MyMethod(object obj)
{
if (!obj.IsAnonymousType())
{
throw new ArgumentException($"Object of this type is not supported!");
}
MyMethod(obj.ToDictionary<int>());
}
public void MyMethod(IDictionary<string, int> dict)
{
// your code here...
}
...
public static class ObjHelper
{
public static IDictionary<string, T> ToDictionary<T>(this object obj)
{
var objType = obj.GetType();
// This call is optimized by compiler
var props = objType.GetProperties();
if (typeof(T) == typeof(object))
{
// we don't need to check if property is of certain type
return props?.ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
}
// It will ignore all types except of T
return props?.Where(p => p.PropertyType == typeof(T)).ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
}
public static bool IsAnonymousType(this object obj)
{
var type = obj.GetType();
if (type == null)
{
throw new ArgumentNullException("type");
}
return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
&& type.IsGenericType && type.Name.Contains("AnonymousType")
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
&& (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
}
}
And call it:
MyMethod(new
{
foo = 15,
bar = 8
})
Let's compare to normal dict call:
MyMethod(new Dictionary<string, int>()
{
{ "foo", 15 },
{ "bar", 8 },
})
Average performance for 100000 operations in ms:
- call with anonymous class: 270
- call with Dictionary: 10