如何获取 class 的属性,这些属性是 class 的 IEnumerable 或从 class 继承的 class 的 IEnumerable

How to get properties of a class which are IEnumerable of a class or an IEnumerable of a class inherited from that class

在 c# 中,我有一个 class,上面有 returns IEnumerables 的属性。

public class MyClass
{
   public IEnumerable<MyPropClass1> Prop1 { get { return _prop1; } }
   public IEnumerable<MyPropClass2> Prop2 { get { return _prop2; } }
   public IEnumerable<AnotherClassAltogether> Prop3 {get {return _prop3; } }
   ...
}

假设 MyPropClass1 和 MyPropClass2 都继承自 MyPropBaseClass 但 AnotherClassAltogether 没有。

从 MyClass 获取所有属性的最简单方法是什么,这些属性要么是某个 class 的 IEnumerable,要么是从链中某处继承的 class 的 IEnumerable class?

例如如果我想在 MyClass 中查询基于模板化为基于 MyPropBaseClass 的东西的 IEnumerables 的属性,那么它应该 return Prop1 和 Prop2

为了更清楚(希望解决接近投票)一个伪函数来回答这个问题是这样的:

var properties = GetIEnumerablePropertiesOfType(typeof(MyClass), typeof(MyPropBaseClass))

这将 return 包含 Prop1 和 Prop2 的属性列表(作为 System.Reflection.PropertyInfo 的可枚举)

using System;
using System.Reflection;    
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Program
{
    public class MyPropClass{}
    public class MyPropClass1 : MyPropClass{}
    public class MyPropClass2 : MyPropClass{}
    public class AnotherClassAltogether {}

    public class MyClass
    {
         public object Prop_Wrong { get; set; }
         public IEnumerable Prop_Wrong_IEnumerable { get; set; }
         public IEnumerable<MyPropClass1> Prop1 { get; set; }
         public IEnumerable<MyPropClass2> Prop2 { get; set; } 
         public IEnumerable<AnotherClassAltogether> Prop3 {get; set; }
    }

    public static IEnumerable<PropertyInfo> GetIEnumerablePropertiesOfType(Type targetType, Type lookFor)
    {
        return targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(x => x.PropertyType.IsGenericType
                     && x.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
                     && x.PropertyType.GenericTypeArguments.Single().IsAssignableTo(lookFor));
    }

    public static void Main()
    {
        foreach (var item in GetIEnumerablePropertiesOfType(typeof(MyClass), typeof(MyPropClass)))
        {
            Console.WriteLine($"Property {item.Name} of type {item.PropertyType}");
        }
    }
}