Check if the object is of type Dictionary or Union of Dictionaries

729 Views Asked by At

I have a function

public static async void MyFunction(object Obj)
{
    if (Obj.GetType() == typeof(Dictionary<string, string>))
    {
        // My Code
    }
}

I want to check if parameter Obj is of type Dictionary<string, string> or Dictionary<string, string>.Union(Dictionary<string, string>).

What || condition should I put in the above if statement so that it will execute if block if the object passed to the function is of type Dictioary or Union of Dictionaries?

How do I do it?

1

There are 1 best solutions below

0
NetMage On

Using an extension method:

public static bool IsAssignableToGenericType(this Type givenType, Type genericType) {
    if (givenType.IsGenericType && givenType.IsGenericEqual(genericType))
        return true;

    if (givenType.GetInterface(genericType.Name) != null)
        return true;

    foreach (var it in givenType.GetInterfaces())
        if (it.IsAssignableToGenericType(genericType))
            return true;

    var baseType = givenType.BaseType;
    if (baseType == null)
        return false;

    return baseType.IsAssignableToGenericType(genericType);
}

You can test:

if (Obj.GetType().IsAssignableToGenericType(typeof(IEnumerable<KeyValuePair<string,string>>))) {

This does not guarantee Obj is the product of a call to Union. If you need to do that, you need to delve into the type.

Using some extension methods to make Reflection easier:

public static class ObjectExt {
    public static object GetPrivateValue<T>(this T obj, string memberName) =>
        obj.GetType().GetPropertyOrField(memberName, BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public).GetValue(obj);
}

public static class TypeExt {
    public static MemberInfo GetPropertyOrField(this Type t, string memberName, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
        t.GetMember(memberName, bf).Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property).Single();
}

public static class MemberInfoExt {
    public static object GetValue(this MemberInfo member, object srcObject) {
        switch (member) {
            case FieldInfo mfi:
                return mfi.GetValue(srcObject);
            case PropertyInfo mpi:
                return mpi.GetValue(srcObject);
            case MethodInfo mi:
                return mi.Invoke(srcObject, null);
            default:
                throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or MethodInfo", nameof(member));
        }
    }
}

You can determine that the object is from a Union of Dictionary. Note that this depends on internals of .Net Core and may not work in the future:

var isDictUnion = (Obj.GetType() == unionType) && (Obj.GetPrivateValue("_first").GetType() == dictType) && (Obj.GetPrivateValue("_second").GetType() == dictType);