C#反映匹配类型列表<t>其中T IsSubClass(Foo)</t>

时间:2013-06-07 09:47:38

标签: c# .net generics reflection

我有一个包含List<T>属性的类。其中一些属性,T是一个继承自Class的类,比如说Foo。

public class Foo {}
public class MyTypeA : Foo {}
public class MyTypeB : Foo {}

// Not : Foo
public class MyTypeC {}

public class Bar 
{
    // I can Match these
    public MyTypeA PropA { get; set; }
    public MyTypeB PropB { get; set; }

    // How can I match these based on IsSubclassOf(Foo)
    public List<MyTypeA> PropListA { get; set; }
    public List<MyTypeB> PropListB { get; set; }

    // Do not match the props below
    public MyTypeC PropC { get; set; }
    public List<MyTypeC> PropListC { get; set; }
    public List<string> PropListString { get; set; }

}    

我已经成功匹配属于Foo子类的属性,如下所示。

foreach (var oProp in T.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
    // Find Prop : Foo
    if( oProp.PropertyType.IsSubclassOf( typeof(Foo) ) )
    {
        // Add Property to dictionary
        aPropInheritType.Add(
            oProp.Name, 
            oProp
        );
    }

    // Match List<T>  where T : Foo
    // How do I test for Generic List that's Type T is a subclass 
    // of the class Foo ?

}

我看到Type类有许多Generic Properties但是无法获取Generic List的Type然后针对IsSubclassOf(Foo)进行测试。

2 个答案:

答案 0 :(得分:3)

要测试属性是否具有返回类型List<T>,请使用下一个代码:

Type returnType = oProp.PropertyType;
if(returnType.IsGenericType && 
   returnType.GetGenericTypeDefinition() == typeof(List<>) &&
   typeof(Foo).IsAssignableFrom(returnType.GetGenericArguments()[0]))
{
   //property is of type List<T>, where T is derived from Foo
}

答案 1 :(得分:1)

这是我从微软框架中窃取的一个小宝石(我认为它是在EF二进制文件中)。

    private static Type GetTypeOfList(PropertyInfo changedMember)
    {
        var listType = from i in changedMember.PropertyType.GetInterfaces()
                       where i.IsGenericType
                       let generic = i.GetGenericTypeDefinition()
                       where generic == typeof (IEnumerable<>)
                       select i.GetGenericArguments().Single();
        return listType.SingleOrDefault();
    }

你只需要测试

    Type listType = ...
    var tInListType = GetTypeOfList(listType);
    return tInListType.IsAssignableFrom(typeof(Foo));