找出一个types是否实现了一个通用接口
假设我有一个typesMyType。 我想要做到以下几点:
- 找出MyType是否实现了IList接口,对于一些T.
- 如果(1)的答案是肯定的,找出T是什么。
这似乎是做到这一点的方法是GetInterface(),但只能让你search一个特定的名称。 有没有一种方法来search“IListforms的所有接口”(如果可能的话,如果接口是IList的子接口,它也会有用)。
相关: 如何确定一个types是否实现了一个特定的通用接口types
// 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] ;
编辑:即使IDerivedFromList<>
实现IDerivedFromList<>
但不直接IList<>
, IList<>
将显示在由GetInterfaces()
返回的数组中。
更新:添加一个检查的边缘情况下,其中myType
是通用接口的问题。
使用reflection(和一些LINQ),你可以很容易地做到这一点:
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(); }
首先,你得到的是types上的接口,并且只对那些genericstypes的接口进行过滤。
然后,您将获得这些接口types的genericstypes定义,并查看它是否与IList<>
相同。
从那里,获取原始接口的通用参数是一件简单的事情。
请记住,一个types可以有多个IList<T>
实现,这就是返回IEnumerable<Type>
原因。
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); }
作为辅助方法扩展
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); }
示例用法:
var testObject = new Dictionary<int, object>(); result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!
使用Anton Tykhyy的build议,下面是一个小的扩展方法来检查某种types是否实现了一个具有一个genericstypes参数的generics接口:
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; } }
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
如果我正确理解你的问题,这就是你正在做的事情。 如果没有,请进一步解释。
public class MyType : ISomeInterface { } MyType o = new MyType(); if(o is ISomeInterface) { }
编辑:如果你改变你的问题,请添加你编辑的事实。因为现在我的答案看起来像不属于。
在这种情况下,这是一个非常大的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