2011-02-10 74 views
431

是否反射C#提供了一種方法來確定是否某些給定System.Type型車型的一些接口?如何確定一個類型實現用C#反射界面

public interface IMyInterface {} 

public class MyType : IMyInterface {} 

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

回答

705

你把我的頭頂部的幾個選擇

  1. typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

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

25
typeof(IMyInterface).IsAssignableFrom(someclass.GetType()); 

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

如果你已經有了類的實例的更好的方法是簡單地`SomeClass的是IMyInterface`因爲不涉及反射的性價比可言。所以,雖然沒有錯,但它不是一個理想的做法。 – 2012-07-27 20:17:02

+1

@James - 同意。即使Resharper也給出了相同的建議。 – 2013-06-11 09:24:43

+0

@ JamesJ.ReganIV你應該張貼作爲答案,我幾乎錯過了你的評論 – reggaeguitar 2014-11-03 21:29:52

10
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調用將最終使用)更安全。

4

正如別人已經提到: 本傑明4月10日在'13 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>(); 
5

修改傑夫的答案以獲得最佳性能(由於性能測試由皮埃爾·阿爾諾):

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); 
0

什麼阿布t

if(MyType as IMyInterface != null) 

0

什麼

typeof(IWhatever).GetTypeInfo().IsInterface 
3

我只是做:

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因爲這是更直觀。我總是得到IsAssignableFrom flip-flopped。

0

IsAssignableFrom現在移動到所屬類別所以.... typeof運算(ISMSRequest).GetTypeInfo()。IsAssignableFrom(typeof運算(T).GetTypeInfo())

0

一個正確的答案是

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

然而,

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

可能會返回一個錯誤的結果,如下面的代碼顯示了串並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