2013-08-14 23 views
20

Tôi có một giao diệnKiểm tra xem một loại thực hiện một giao diện chung mà không xem xét các đối số kiểu generic

public interface MyInterface<TKey, TValue> 
{ 
} 

Triển khai là không thích hợp. Bây giờ tôi muốn kiểm tra xem một loại nhất định có phải là triển khai thực hiện giao diện đó hay không. Phương pháp này không thành công cho

public class MyClass : MyInterface<int, string> 
{ 
} 

Nhưng tôi không biết cách kiểm tra.

public void CheckIfTypeImplementsInterface(Type type) 
{ 
    var result1 = typeof(MyInterface<,>).IsAssignableFrom(type); --> false 
    var result2 = typeof(MyInterface<int,string>).IsAssignableFrom(type); --> true 
} 

Tôi phải làm gì để kết quả là đúng?

+0

Bạn đã cân nhắc tạo giao diện 'MyInterface' và có' MyInterface : MyInterface'? –

Trả lời

33

Theo như tôi biết, cách duy nhất để làm điều này là nhận tất cả các giao diện và xem liệu định nghĩa chung có phù hợp với loại giao diện được yêu cầu hay không.

bool result1 = type.GetInterfaces() 
    .Where(i => i.IsGenericType) 
    .Select(i => i.GetGenericTypeDefinition()) 
    .Contains(typeof(MyInterface<,>)); 

EDIT: Như Jon chỉ ra trong các ý kiến, bạn cũng có thể làm:

bool result1 = type.GetInterfaces() 
    .Where(i => i.IsGenericType) 
    .Any(i => i.GetGenericTypeDefinition() == typeof(MyInterface<,>)); 
+4

Bạn có thể thay đổi hai số cuối của bạn thành: '.Any (i => i.GetGenericTypeDefinition() == typeof (MyInterface <,>))' –

2

Nói chung, hành vi như vậy chỉ được yêu cầu trong trường hợp một giao diện chứa một số chức năng mà không phụ thuộc vào thông số loại chung. Nếu bạn có quyền kiểm soát các giao diện, giải pháp tốt nhất là có các phần phụ thuộc vào loại được kế thừa từ phần phụ thuộc không phải kiểu. Ví dụ, nếu các giao diện bộ sưu tập hiện không tồn tại, người ta có thể xác định họ một cái gì đó như:

interface ICountable 
    { CollectionAttribute Attributes {get;} int Count {get;} } 
interface ICollection<T> : IEnumerable<T> ICountable 
    { ... and other stuff ... } 

Có phải một điều như vậy được thực hiện với ICollection, sau đó mã được mong đợi một IEnumerable<Animal> nhưng có một đối tượng kiểu CatList chỉ thực hiện IList<Cat> sẽ không có vấn đề khi sử dụng thành viên Count của đối tượng đó (lưu ý rằng List<Animal> triển khai ICollection không chung chung, nhưng việc triển khai IList<Animal> khác có thể không).

Vì nó là, nếu bạn đang mắc kẹt với nhiệm vụ có mã bằng cách nào đó tìm ra phương pháp Count của ICollection<Cat> khi bạn đang mong một IEnumerable<Animal>, nó có thể là đáng giá để xây dựng một cái gì đó giống như một Dictionary<Type, Func<IEnumerable<Animal>, int> để một khi bạn đã thấy rằng CatList thực hiện ICollection<Cat>.Count bạn có thể xây dựng một đại biểu cho một phương pháp sẽ đưa đối số của nó đến ICollection<Cat>, gọi Count trên đó và trả về kết quả của nó. Nếu bạn có một từ điển như vậy, thì nếu bạn được cấp một CatList khác, bạn sẽ có thể đơn giản gọi đại biểu từ từ điển.

+0

Hoàn toàn phát triển, nhưng trong trường hợp của tôi, tôi chỉ muốn kiểm tra cơ bản trong thuộc tính ' [CustomAttribute (typeof (ClassName))] 'và tôi yêu cầu ClassName để thực hiện interface.Later trong mã, tôi biết cả hai thuộc tính generic và có thể sử dụng sự phản chiếu để tạo ra một cá thể mới của ClassName –

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