Using Isassignablefrom with 'Open' Generic Types

Using IsAssignableFrom with 'open' generic types

From the answer to another question:

public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();

foreach (var it in interfaceTypes)
{
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
return true;
}

if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;

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

return IsAssignableToGenericType(baseType, genericType);
}

IsAssignableFrom when interface has generics, but not the implementation

I think you have to call GetInterfaces() from your StringMapper and test each one for IsGenericType. Last but not least get the open type (IMapper<,>) of each generic one by calling GetGenericTypeDefinition() and test if it matches typeof(IMapper<,>).

That's all you can do. But be aware, if the class inherits from another base class which also implements some interfaces, these won't be listed. In that case you have to recursevly run down through the BaseType properties and do the above down till the BaseType is null.

IsAssignableFrom on GenericType

There is not an inheritance relationship between a generic type definition and a closed generic type. Therefore, IsAssignableFrom will not work.

However, I use this little extension method to achieve what your after:

public static bool IsGenericTypeOf(this Type t, Type genericDefinition)
{
Type[] parameters = null;
return IsGenericTypeOf(t, genericDefinition, out parameters);
}

public static bool IsGenericTypeOf(this Type t, Type genericDefinition, out Type[] genericParameters)
{
genericParameters = new Type[] { };
if (!genericDefinition.IsGenericType)
{
return false;
}

var isMatch = t.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
if (!isMatch && t.BaseType != null)
{
isMatch = IsGenericTypeOf(t.BaseType, genericDefinition, out genericParameters);
}
if (!isMatch && genericDefinition.IsInterface && t.GetInterfaces().Any())
{
foreach (var i in t.GetInterfaces())
{
if (i.IsGenericTypeOf(genericDefinition, out genericParameters))
{
isMatch = true;
break;
}
}
}

if (isMatch && !genericParameters.Any())
{
genericParameters = t.GetGenericArguments();
}
return isMatch;
}

With sample usage:

Nullable<int> value = 9;
Assert.IsTrue(value.GetType().IsGenericTypeOf(typeof(Nullable<>)));

Determine if object is an instance of a generic base class, any generic type

The problem is that DrevidedC1 is not a sublcass of Class1<T>, it's a subclass of Class1<int>. Make sure you understand this subtle diference; Class1<T> is a open type (T can be anything, it hasn't been set) while DerivedC1 extends a closed type Class1<int> (it's not open in T anymore, T is set to int and only int). So when you do the following:

 typeof(DerivedC1).IsSubclassOf(typeof(Class1<>))

The answer is evidently false.

What you need to do is check if the generic type definition of DerivedC1's base type (think of it as the corresponding open generic type of Class1<int>) equals Class1<T> which it clearly does.

The correct code is therefore:

typeof(DerivedC1).BaseType.GetGenericTypeDefinition() == typeof(Class1<>));

Or better yet, as Matías Fidemraizer states in his answer:

typeof(DerivedC1).BaseType.GetGenericTypeDefinition().IsAssignableFrom(typeof(Class1<>)));

IDictionary`2 not assignable from Dictionary`2

You need to search the type's interfaces and check if any are an instantiation of the IDictionary<K, V> interface:

bool isDict = type.GetInterfaces().Any(it => it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IDictionary<,>));


Related Topics



Leave a reply



Submit