Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell whether a Type implements IList<>?

Tags:

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?

like image 950
Joe White Avatar asked Jun 04 '09 16:06

Joe White


People also ask

What is IList<>?

In C# IList interface is an interface that belongs to the collection module where we can access each element by index. Or we can say that it is a collection of objects that are used to access each element individually with the help of an index. It is of both generic and non-generic types.

When to use List or IList?

The main difference between List and IList in C# is that List is a class that represents a list of objects which can be accessed by index while IList is an interface that represents a collection of objects which can be accessed by index.

Why use IList instead of List c#?

Using IList instead of List makes writing unit tests significantly easier. It allows you to use a 'Mocking' library to pass and return data. The other general reason for using interfaces is to expose the minimum amount of knowledge necessary to the user of an object.


1 Answers

In fact, you cannot have an instance of a generic type definition. Therefore, the IsAssignableFrom() method works as expected. To achieve what you want, do the following:

public bool IsGenericList(Type type) {     if (type == null) {         throw new ArgumentNullException("type");     }     foreach (Type @interface in type.GetInterfaces()) {         if (@interface.IsGenericType) {             if (@interface.GetGenericTypeDefinition() == typeof(ICollection<>)) {                 // if needed, you can also return the type used as generic argument                 return true;             }         }     }     return false; } 

Just out of curiosity, what do you need this for?

like image 185
Lucero Avatar answered Sep 17 '22 18:09

Lucero