首页 文章

如何确定类型是否实现了具有C#反射的接口

提问于
浏览
464

C# 中的 reflection 是否提供了一种方法来确定某些给定的 System.Type 类型模型是否有某些接口?

public interface IMyInterface {}

public class MyType : IMyInterface {}

// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);

11 回答

  • 5

    我有一些选择

    • typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

    • typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

    对于通用接口,它有点不同 .

    typeof(MyType).GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))
    
  • -1

    使用Type.IsAssignableFrom

    typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
    
  • 2
    typeof(IMyInterface).IsAssignableFrom(someclass.GetType());
    

    要么

    typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
    
  • 5
    public static bool ImplementsInterface( this Type type, Type ifaceType ) {
            Type[] intf = type.GetInterfaces();
            for ( int i = 0; i < intf.Length; i++ ) {
                if ( intf[ i ] == ifaceType ) {
                    return true;
                }
            }
            return false;
        }
    

    我认为这是正确的版本,原因有三:

    1)它使用GetInterfaces而不是IsAssignableFrom,因为IsAssignableFrom最终在多次检查后调用GetInterfaces,所以它更快 .
    2)它迭代本地数组,因此不会有边界检查 .
    3)它使用为Type定义的==运算符,因此可能比Equals方法(Contains调用最终将使用)更安全 .

  • 781

    修改Jeff的答案以获得最佳性能(感谢Pierre Arnaud的性能测试):

    var type = typeof(MyType);
    var implementsInterface = typeof(IMyInterface).IsAssignableFrom(type) && type.IsClass;
    

    要查找在给定 Assembly 中实现接口的所有类型:

    var implementations = typeof(TypeInTargetAssembly).Assembly.GetTypes()
                              .Where(t => typeof(IMyInterface).IsAssignableFrom(t) && t.IsClass);
    
  • 49

    我已经做了:

    public static bool Implements<I>(this Type source) where I : class
    {
      return typeof(I).IsAssignableFrom(source);
    }
    

    我希望我能说 where I : interface ,但 interface 不是通用参数约束选项 . class 尽可能接近 .

    用法:

    if(MyType.Implements<IInitializable>())
      MyCollection.Initialize();
    

    我刚才说 Implements 因为这更直观 . 我总是被甩掉了.736633_ .

  • -1

    正如其他人已经提到的那样:Benjamin 2013年4月10日22:21“

    确实很容易不注意并且反过来获得IsAssignableFrom的论据 . 我现在将使用GetInterfaces:p -

    好吧,另一种方法是创建一种简短的扩展方法,在某种程度上满足“最常见”的思维方式(同意这是一个非常小的个人选择,使其根据一个人的偏好略微“更自然” ):

    public static class TypeHelpers
    {
        public static Boolean IsAssignableTo(Type type, Type assignableType)
        {
            return assignableType.IsAssignableFrom(type);
        }
    }
    
    public static class TypeExtensions
    {
        public static Boolean IsAssignableTo(this Type type, Type assignableType)
        {
            return TypeHelpers.IsAssignableTo(type, assignableType);
        }
    }
    

    为什么不进一步通用(不确定它是否真的那么有趣,我认为我只是传递了另一个'语法'糖):

    public static class TypeHelpers
    {
        public static Boolean IsAssignableTo(Type type, Type assignableType)
        {
            return assignableType.IsAssignableFrom(type);
        }
    
        public static Boolean IsAssignableTo<TAssignable>(Type type)
        {
            return TypeHelpers.IsAssignableTo(type, typeof(TAssignable));
        }
    }
    
    public static class TypeExtensions
    {
        public static Boolean IsAssignableTo(this Type type, Type assignableType)
        {
            return TypeHelpers.IsAssignableTo(type, assignableType);
        }
    
        public static Boolean IsAssignableTo<TAssignable>(this Type type)
        {
            return TypeHelpers.IsAssignableTo<TAssignable>(type);
        }
    }
    

    我认为这可能更自然,但再一次只是个人意见的问题:

    var isTrue = michelleType.IsAssignableTo<IMaBelle>();
    
  • 4

    一个正确的答案是

    typeof(MyType).GetInterface(nameof(IMyInterface)) != null;
    

    然而,

    typeof(MyType).IsAssignableFrom(typeof(IMyInterface));
    

    可能会返回错误的结果,如下面的代码显示string和IConvertible:

    static void TestIConvertible()
        {
            string test = "test";
            Type stringType = typeof(string); // or test.GetType();
    
            bool isConvertibleDirect = test is IConvertible;
            bool isConvertibleTypeAssignable = stringType.IsAssignableFrom(typeof(IConvertible));
            bool isConvertibleHasInterface = stringType.GetInterface(nameof(IConvertible)) != null;
    
            Console.WriteLine($"isConvertibleDirect: {isConvertibleDirect}");
            Console.WriteLine($"isConvertibleTypeAssignable: {isConvertibleTypeAssignable}");
            Console.WriteLine($"isConvertibleHasInterface: {isConvertibleHasInterface}");
        }
    

    结果:

    isConvertibleDirect: True
     isConvertibleTypeAssignable: False
     isConvertibleHasInterface: True
    
  • 26

    IsAssignableFrom 现在移至 TypeInfo

    typeof(ISMSRequest).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo());
    
  • 2

    关于什么

    if(MyType as IMyInterface != null)
    

  • 10

    关于什么

    typeof(IWhatever).GetTypeInfo().IsInterface
    

相关问题