2011-06-21 39 views
6

Tôi đang cố gắng viết một phương thức sử dụng sự phản chiếu để trả về tất cả các lớp là các lớp con của một lớp sử dụng Generics. loại chung. Vì vậy, ví dụ, trong EF tôi muốn tìm tất cả các lớp bản đồ. Các lớp được thiết lập như:Làm thế nào tôi có thể sử dụng sự phản chiếu để trả về tất cả các lớp phân lớp từ một generic, mà không đưa ra một kiểu generic cụ thể

public class clientMap : EntityTypeConfiguration<Client> {} 

Tôi muốn tìm tất cả các lớp học trong lắp ráp của tôi đó là một lớp con của các EntityTypeConfiguration<T>, mà không chỉ định Client như T đặc biệt. Tôi muốn trả về cấu hình kiểu thực thể cho tất cả các lớp trong ứng dụng của tôi mà không cần mã hóa nó.

Nếu không có generics tôi sẽ lặp qua các loại trong lắp ráp, kiểm tra xem type.IsSubclassOf(typeof(BaseClass)), tuy nhiên tôi không chắc chắn làm thế nào để làm điều này khi giao dịch với Generics.

+2

Duplicate ? http://stackoverflow.com/questions/457676/c-reflection-check-if-a-class-is-derived-from-a-generic-class –

+0

Ah không thấy điều đó, cảm ơn – KallDrexx

Trả lời

10

Tôi tin rằng bạn muốn một cái gì đó như thế này:

static class TypeExtensions { 
    public static bool IsDerivedFromOpenGenericType(
     this Type type, 
     Type openGenericType 
    ) { 
     Contract.Requires(type != null); 
     Contract.Requires(openGenericType != null); 
     Contract.Requires(openGenericType.IsGenericTypeDefinition); 
     return type.GetTypeHierarchy() 
        .Where(t => t.IsGenericType) 
        .Select(t => t.GetGenericTypeDefinition()) 
        .Any(t => openGenericType.Equals(t)); 
    } 

    public static IEnumerable<Type> GetTypeHierarchy(this Type type) { 
     Contract.Requires(type != null); 
     Type currentType = type; 
     while (currentType != null) { 
      yield return currentType; 
      currentType = currentType.BaseType; 
     } 
    } 
} 

Các xét nghiệm pass:

class Foo<T> { } 
class Bar : Foo<int> { } 
class FooBar : Bar { } 

[Fact] 
public void BarIsDerivedFromOpenGenericFoo() { 
    Assert.True(typeof(Bar).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 

[Fact] 
public void FooBarIsDerivedFromOpenGenericFoo() { 
    Assert.True(typeof(FooBar).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 

[Fact] 
public void StringIsNotDerivedFromOpenGenericFoo() { 
    Assert.False(typeof(string).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 
+0

Điều gì sẽ 'openGenericType' được trong mã thực tế? 'EntityTypeConfiguration <>' hoặc nên có gì đó trong ngoặc? – KallDrexx

+0

Đối với trường hợp của bạn, 'typeof (EntityTypeConfiguration <>)'. Lưu ý mã và thử nghiệm làm cho điều này rõ ràng. – jason

+1

Hoạt động ngoạn mục :) – KallDrexx

0

như xa như tôi hiểu trường hợp của bạn như sau nên đủ

type.BaseType != null && 
type.BaseType.MetadataToken == typeof(EntityTypeConfiguration<>).MetadataToken 
Các vấn đề liên quan