smoksnes
smoksnes

Reputation: 10851

Detect if it's a Dictionary and the key is assignable from a specific type

I'm working on a custom JsonConverter, and override the CanConvert-method.

public override bool CanConvert(Type objectType)
{
    return (typeof(IDictionary).IsAssignableFrom(objectType) ||
            TypeImplementsGenericInterface(objectType, typeof(IDictionary<,>)));
}

private static bool TypeImplementsGenericInterface(Type concreteType, Type interfaceType)
{
    return concreteType.GetInterfaces()
           .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType);
}

Very much inspired from this answer. The thing is that I only want to return true if the key of the dictionary is of a specific type. For example, I only want to return true if the key is of type Bar, or inherits/implements Bar. The value doesn't matter. The value can be of any type.

Dictionary<string, int> // false
Dictionary<Bar, string> // true
Dictionary<Foo, string> // false
Dictionary<Bar, Foo> // true
Dictionary<BarSubClass, Foo> // true

How can I, from a Type, detect if it's a Dictionary and the key is assignable from a specific type?

What I've tried so far:

typeof(IDictionary<Bar, object>).IsAssignableFrom(objectType)

Unfortunately this returns false.

Upvotes: 3

Views: 680

Answers (1)

Sefe
Sefe

Reputation: 14007

You have to check the generic type and the first type argument (TKey):

concreteType.GetInterfaces().Any(i => i.IsGenericType &&
    (i.GetGenericTypeDefinition() == typeof(IDictionary<,>)) &&
    typeof(Bar).IsAssignableFrom(i.GetGenericArguments()[0]));

Upvotes: 4

Related Questions