g.t.w.d
g.t.w.d

Reputation: 621

IDictionary`2 is not assignable from IDictionary?

I have a property on my ViewModel that is of type IDictionary<string, string>. I am going through the list of properties on that ViewModeland using reflection to determine if it is a dictionary.

Currently I have:

if (typeof(IDictionary).IsAssignableFrom(propDescriptor.PropertyType))

However, that is always false because propDescriptor.PropertyType is IDictionary`2. Any ideas how I can get that to work? Also, why isn't that working?


I just changed my property to be IDictionary instead of IDictionary.

EDIT: Not sure where my generics went, but the second IDictionary in the sentence above has string, string.

Upvotes: 1

Views: 1396

Answers (4)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

The reason why it's not working is that the generic IDictionary<,> interface does not have the non-generic IDictionary as a base interface.

Maybe this is what you want:

var type = propDescriptor.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
{ // ...

Edit: The above code will only check if type is declared as IDictionary<X, Y> for some X and Y. If you also want to handle cases where type represents a class or struct that implements IDictionary<X, Y> (or even an interface derived from IDictionary<X, Y>), then try this:

Func<Type, bool> isGenericIDict =
  t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>);
var type = propDescriptor.PropertyType;
if (isGenericIDict(type) || type.GetInterfaces().Any(isGenericIDict))
{ // ..

Upvotes: 5

D Stanley
D Stanley

Reputation: 152566

It's not IDictionary`2. It's the compiler-generated class name for a generic IDictionary<TKey,TValue>, which is not directly castable to an IDictionary.

Upvotes: 1

Adi Lester
Adi Lester

Reputation: 25201

IDictionary`2 is not derived from IDictionary as can be seen in its definition:

public interface IDictionary<TKey, TValue> :
    ICollection<KeyValuePair<TKey, TValue>>,
    IEnumerable<KeyValuePair<TKey, TValue>>,
    IEnumerable

Therefore the generic IDictionary<TKey, TValue> is not castable to IDictionary.

Upvotes: 1

lante
lante

Reputation: 7336

IDictionary is different from IDictionary< T, K >.

Use:

if (typeof(IDictionary<string, string>).IsAssignableFrom(propDescriptor.PropertyType))

Upvotes: 0

Related Questions