Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding out if a type implements a generic interface

Let's say I have a type, MyType. I want to do the following:

  1. Find out if MyType implements the IList interface, for some T.
  2. If the answer to (1) is yes, find out what T is.

It seems like the way to do this is GetInterface(), but that only lets you search by a specific name. Is there a way to search for "all interfaces that are of the form IList" (If possible it woudl also be useful if it worked if the interface was a subinterface of IList.)

Related: How to determine if a type implements a specific generic interface type

like image 555
Alex319 Avatar asked Jul 13 '09 20:07

Alex319


People also ask

How do you find the type of generic type?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.

Can a generic implement an interface?

Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.

When would you use a generic interface?

It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.


2 Answers

// this conditional is necessary if myType can be an interface, // because an interface doesn't implement itself: for example, // typeof (IList<int>).GetInterfaces () does not contain IList<int>! if (myType.IsInterface && myType.IsGenericType &&      myType.GetGenericTypeDefinition () == typeof (IList<>))     return myType.GetGenericArguments ()[0] ;  foreach (var i in myType.GetInterfaces ())     if (i.IsGenericType && i.GetGenericTypeDefinition () == typeof (IList<>))         return i.GetGenericArguments ()[0] ; 

Edit: Even if myType implements IDerivedFromList<> but not directly IList<>, IList<> will show up in the array returned by GetInterfaces().

Update: added a check for the edge case where myType is the generic interface in question.

like image 126
Anton Tykhyy Avatar answered Sep 28 '22 04:09

Anton Tykhyy


Using reflection (and some LINQ) you can easily do this:

public static IEnumerable<Type> GetIListTypeParameters(Type type) {     // Query.     return         from interfaceType in type.GetInterfaces()         where interfaceType.IsGenericType         let baseInterface = interfaceType.GetGenericTypeDefinition()         where baseInterface == typeof(IList<>)         select interfaceType.GetGenericArguments().First(); } 

First, you are getting the interfaces on the type and filtering out only for those that are a generic type.

Then, you get the generic type definition for those interface types, and see if it is the same as IList<>.

From there, it's a simple matter of getting the generic arguments for the original interface.

Remember, a type can have multiple IList<T> implementations, which is why the IEnumerable<Type> is returned.

like image 26
casperOne Avatar answered Sep 28 '22 05:09

casperOne