I want to write a method that uses Reflection to tell whether a given Type implements IList<T>
. For example:
IsGenericList(typeof(int)) // should return false
IsGenericList(typeof(ArrayList)) // should return false
IsGenericList(typeof(IList<int>)) // should return true
IsGenericList(typeof(List<int>)) // should return true
IsGenericList(typeof(ObservableCollection<int>)) // should return true
In my usage, I can assume that the type will always be an instantiated generic type (or something that's not generic at all).
Unfortunately, this isn't as easy as it ought to be. The obvious solution:
public bool IsGenericList(Type type)
{
return typeof(IList<>).IsAssignableFrom(type);
}
doesn't work; it always returns false. Apparently non-instantiated generic types like IList<>
don't implement IsAssignableFrom the way I'd expect them to: IList<>
is not assignable from List<T>
.
I've also tried this:
public bool IsGenericList(Type type)
{
if (!type.IsGenericType)
return false;
var genericTypeDefinition = type.GetGenericTypeDefinition();
return typeof(List<>).IsAssignableFrom(genericTypeDefinition);
}
I.e., turn type
into its non-instantiated generic, like IList<int>
-> IList<>
, and then try IsAssignableFrom again. That will return true when type is an instantiated IList<T>
such as IList<int>
, IList<object>
, etc. But it returns false for classes that implement IList<T>
such as List<int>
, ObservableCollection<double>
, etc., so apparently IList<>
is not assignable from List<>
. Again, not what I would expect.
How do I go about writing IsGenericList and making it work as in the above examples?