Finding out if a type implements a generic interface
// 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.
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.
public static bool Implements<I>(this Type type) where I : class
{
if (!typeof(I).IsInterface)
{
throw new ArgumentException("Only interfaces can be 'implemented'.");
}
return typeof(I).IsAssignableFrom(type);
}
Using Anton Tykhyy's proposal, here is a small Extension Method to check if some type implements a generic interface with one given generic type parameters:
public static class ExtensionMethods
{
/// <summary>
/// Checks if a type has a generic interface.
/// For example
/// mytype.HasGenericInterface(typeof(IList<>), typeof(int))
/// will return TRUE if mytype implements IList<int>
/// </summary>
public static bool HasGenericInterface(this Type type, Type interf, Type typeparameter)
{
foreach (Type i in type.GetInterfaces())
if (i.IsGenericType && i.GetGenericTypeDefinition() == interf)
if (i.GetGenericArguments()[0] == typeparameter)
return true;
return false;
}
}
As a helper method extension
public static bool Implements<I>(this Type type, I @interface) where I : class
{
if(((@interface as Type)==null) || !(@interface as Type).IsInterface)
throw new ArgumentException("Only interfaces can be 'implemented'.");
return (@interface as Type).IsAssignableFrom(type);
}
example usage:
var testObject = new Dictionary<int, object>();
result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!