假设有以下类型定义:

public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}

我如何找出类型Foo是否实现了通用接口IBar<T>时,只有manged类型是可用的?


当前回答

通过使用tck的答案,也可以用以下LINQ查询完成:

bool isBar = foo.GetType().GetInterfaces().Any(x =>
  x.IsGenericType &&
  x.GetGenericTypeDefinition() == typeof(IBar<>));

其他回答

如果你想要一个支持泛型基类型和接口的扩展方法,我扩展了sduplooy的答案:

    public static bool InheritsFrom(this Type t1, Type t2)
    {
        if (null == t1 || null == t2)
            return false;

        if (null != t1.BaseType &&
            t1.BaseType.IsGenericType &&
            t1.BaseType.GetGenericTypeDefinition() == t2)
        {
            return true;
        }

        if (InheritsFrom(t1.BaseType, t2))
            return true;

        return
            (t2.IsAssignableFrom(t1) && t1 != t2)
            ||
            t1.GetInterfaces().Any(x =>
              x.IsGenericType &&
              x.GetGenericTypeDefinition() == t2);
    }

以下内容应该没有任何问题:

bool implementsGeneric = (anObject.Implements("IBar`1") != null);

如果您想为IBar查询提供一个特定的泛型类型参数,您可以捕获AmbiguousMatchException。

作为辅助方法扩展

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!

方法检查类型是否继承或实现泛型类型:

   public static bool IsTheGenericType(this Type candidateType, Type genericType)
    {
        return
            candidateType != null && genericType != null &&
            (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == genericType ||
             candidateType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == genericType) ||
             candidateType.BaseType != null && candidateType.BaseType.IsTheGenericType(genericType));
    }
public interface IFoo<T> : IBar<T> {}
public class Foo : IFoo<Foo> {}

var implementedInterfaces = typeof( Foo ).GetInterfaces();
foreach( var interfaceType in implementedInterfaces ) {
    if ( false == interfaceType.IsGeneric ) { continue; }
    var genericType = interfaceType.GetGenericTypeDefinition();
    if ( genericType == typeof( IFoo<> ) ) {
        // do something !
        break;
    }
}