Let's say I have a type, MyType. I want to do the following:
Find out if MyType implements the IList interface, for some T. 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
// 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.
First
on the results of this method. If you return First
from this method, you're assuming one type parameter which is outright wrong.
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!
Type[] typeArray2 = c.GetInterfaces();
for (int num2 = 0; num2 < typeArray2.Length; num2++)
{
if (this == typeArray2[num2])
{
return true;
}
}
--http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx
If i understand your question correctly, this is what you are trying to do. If not, please explain further.
public class MyType : ISomeInterface
{
}
MyType o = new MyType();
if(o is ISomeInterface)
{
}
edit: if you change your question, please add the fact that you edited..because now my answer looks like it doesn't belong.
In that case, here is a very large LINQ
var item = typeof(MyType).GetInterfaces()
.Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>))
.Select(t => t.GetGenericArguments().First())
.FirstOrDefault();
if( item != null )
//it has a type
Success story sharing
Dictionary<,>
implementsIDictionary<`0, `1>
where'0
and'1
refer to the type parameters ofDictionary<,>
- look it up in ILDasm or similar.