繁体   English   中英

找出类型是否实现了通用接口

[英]Finding out if a type implements a generic interface

假设我有一个类型MyType。 我想做以下事情:

  1. 找出MyType是否为某些T实现了IList接口。
  2. 如果(1)的答案为是,请找出T是什么。

看起来这样做的方法是GetInterface(),但这只允许您按特定名称进行搜索。 有没有办法搜索“IList形式的所有接口”(如果可能的话,如果接口是IList的子接口,它也会有用。)

相关: 如何确定类型是否实现特定的通用接口类型

// 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] ;

编辑:即使myType实现IDerivedFromList<>但不直接IList<> IList<>将通过返回的数组中显示GetInterfaces()

更新:添加了对边缘情况的检查,其中myType是有问题的通用接口。

使用反射(和一些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();
}

首先,您将获取该类型的接口,并仅过滤掉那些通用类型的接口。

然后,您将获得这些接口类型的泛型类型定义,并查看它是否与IList<>相同。

从那里,获得原始接口的泛型参数是一件简单的事情。

请记住,类型可以有多个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的提议,这里有一个小的扩展方法来检查某个类型是否使用一个给定的泛型类型参数实现泛型接口:

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;
    }
}

如果我理解你的问题,这就是你想要做的。 如果没有,请进一步解释。

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
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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM