2011-02-10 31 views

Trả lời

705

Bạn có một vài lựa chọn ra khỏi đỉnh đầu của tôi

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

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

+55

Hãy nhớ rằng typeof (IMyInterface) .IsAssignableFrom (typeof (IMyInterface)) cũng đúng, có thể có kết quả không mong muốn trên mã của bạn. –

+21

Nó chắc chắn là dễ dàng để không chú ý và nhận được các đối số cho 'IsAssignableFrom' ngược. Tôi sẽ đi với 'GetInterfaces' ngay bây giờ: p – Benjamin

+10

Biến thể' IsAssignableFrom (t1) 'là khoảng 3x nhanh hơn' GetInterfaces(). Chứa (t2) 'đối tác trong mã của tôi. –

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

hoặc

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

Nếu bạn đã có một thể hiện của lớp một cách tiếp cận tốt hơn chỉ đơn giản là 'SomeClass là IMyInterface' như không liên quan đến chi phí phản ánh ở tất cả.Vì vậy, trong khi không sai, nó không phải là một cách lý tưởng để làm điều đó. –

+1

@James - Đồng ý. Ngay cả Resharper cũng đưa ra gợi ý tương tự. –

+0

@ JamesJ.ReganIV bạn nên đăng bài đó như một câu trả lời, tôi gần như bỏ lỡ bình luận của bạn – reggaeguitar

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

Tôi nghĩ rằng đây là phiên bản đúng, vì ba lý do:

1) Nó sử dụng getInterfaces và không IsAssignableFrom, nó nhanh hơn kể từ IsAssignableFrom cuối cùng sau một số kiểm tra không gọi GetInterfaces.
2) Nó lặp qua mảng cục bộ, do đó sẽ không có kiểm tra giới hạn.
3) Nó sử dụng toán tử == được định nghĩa cho Type, vì vậy có lẽ an toàn hơn phương thức Equals (có chứa cuộc gọi, cuối cùng sẽ sử dụng).

+7

+1 cho nội dung, tôi ghét không gian xung quanh các parens và niềng răng Ai Cập mặc dù. Ngoài ra toàn bộ phương thức có thể được viết dưới dạng: return type.GetInterfaces() .Tất cả (t => t == ifaceType); – reggaeguitar

+0

Type.IsAssignableFrom() internaly hoạt động chính xác như mã của bạn – devi

+0

Ngoài ra tại sao không gõ.GetInterfaces() .Có chứa (ifaceType) không sử dụng LINQ. –

4

Khi ai đó đã đề cập: Benjamin 10 Tháng 4 '13 tại 22:21"

Nó chắc chắn là dễ dàng để không chú ý và nhận được những lập luận cho IsAssignableFrom ngược.Tôi sẽ đi với GetInterfaces ngay bây giờ: p -

Vâng, một cách khác chỉ là tạo ra một phương pháp mở rộng ngắn đáp ứng, một cách nào đó, cách suy nghĩ "thông thường nhất" (và đồng ý đây là ít sự lựa chọn cá nhân để làm cho nó hơi "tự nhiên hơn" dựa trên sở thích của một người):

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

Và tại sao không đi chung chung hơn một chút (cũng không chắc chắn nếu nó thực sự là thú vị, tôi cũng giả định tôi chỉ chuyển một đoạn đường 'cú pháp' khác):

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

Tôi nghĩ rằng nó có thể là tự nhiên nhiều hơn nữa theo cách đó, nhưng một lần nữa chỉ là vấn đề của những ý kiến ​​rất cá nhân:

var isTrue = michelleType.IsAssignableTo<IMaBelle>(); 
+3

Có lý do nào khiến bạn không chỉ thực hiện trực tiếp phương pháp mở rộng không? Tôi có nghĩa là điều này cho phép bạn gọi nó theo cả hai cách, nhưng tại sao bạn lại cần phải làm điều đó? – MarqueIV

5
câu trả lời

Sửa Jeff cho hiệu suất tối ưu (nhờ kiểm tra hiệu suất của Pierre Arnaud):

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

Để tìm tất cả các loại mà thực hiện một giao diện trong một Assembly đưa ra:

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

gì abou t

if(MyType as IMyInterface != null) 

?

+2

Điều này hiển nhiên khi tôi có một cá thể. Không hữu ích khi tôi có một kiểu từ phản chiếu – edc65

0

gì về

typeof(IWhatever).GetTypeInfo().IsInterface 
3

tôi chỉ làm:

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

Tôi ước gì tôi có thể nói where I : interface, nhưng interface không phải là một lựa chọn tham số hạn chế chung. class là gần như nó được.

Cách sử dụng:

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

Tôi chỉ nói Implements bởi vì đó là trực quan hơn. Tôi luôn nhận được IsAssignableFrom bị lật.

0

IsAssignableFrom hiện đang chuyển sang TypeInfo vậy .... typeof (ISMSRequest) .GetTypeInfo(). IsAssignableFrom (typeof (T) .GetTypeInfo())

0

Một câu trả lời đúng là

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

Tuy nhiên,

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

có thể trả về một kết quả sai, vì mã sau đây cho thấy với chuỗi và 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}"); 
    } 

Kết quả:

isConvertibleDirect: True 
isConvertibleTypeAssignable: False 
isConvertibleHasInterface: True 
+0

Như bạn có thể thấy trong câu trả lời được chấp nhận, bạn đã hoán đổi các kiểu sử dụng 'IsAssignableFrom'. Giống như Benjamin và Ehouarn cảnh báo. – VV5198722

Các vấn đề liên quan