2011-06-21 41 views
6

我正在尝试编写一个使用反射的方法来返回所有使用泛型的类的子类,而不受泛型类型。因此,例如,在EF中我想找到所有的映射类。这些类设置,如:如何使用反射从泛型中继承所有类,而不提供特定的泛型类型

public class clientMap : EntityTypeConfiguration<Client> {} 

我想找到我的组件,该组件的EntityTypeConfiguration<T>一个子类,所有类,而不指定Client为T明确。我想在我的应用程序中为所有类返回实体类型配置,而无需对其进行硬编码。

没有泛型我会遍历程序集中的类型,检查是否type.IsSubclassOf(typeof(BaseClass)),但是我不知道在处理泛型时如何做到这一点。

+2

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

+0

啊没有看到,谢谢 – KallDrexx

回答

10

我相信你想是这样的:

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

这些测试都通过了:

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

什么'openGenericType'在实际的代码? 'EntityTypeConfiguration <>'或者应该在括号内? – KallDrexx

+0

对于你的情况,'typeof(EntityTypeConfiguration <>)'。注意代码和测试清楚地表明了这一点。 – jason

+1

壮观地工作:) – KallDrexx

0

据我了解你的情况下应该是足够

type.BaseType != null && 
type.BaseType.MetadataToken == typeof(EntityTypeConfiguration<>).MetadataToken