在通用函数中从 类 中的 类 获取属性

Getting properties from classes within classes in a generic function

这个问题是基于先前问题的后续问题:

我有以下通用函数,它查找属性并根据作为参数给出的 属性 对列表进行排序:

public static void SortList<T>(ref List<T> list, String sortExpression, SortDirection sortDirection) { 
    IList<PropertyInfo> properties = typeof(T).GetProperties();
    foreach(var prop in properties){
        if(prop.Name.Equals(sortExpression)){
            if (sortDirection == SortDirection.Ascending) {
                list.Sort(delegate(T t1, T t2) { return prop.GetValue(t1).ToString().CompareTo(prop.GetValue(t2).ToString()); });
            } else {
                list.Sort(delegate(T t1, T t2) { return prop.GetValue(t2).ToString().CompareTo(prop.GetValue(t1).ToString()); });
            }
            return;
        }
    }
}

这将搜索 class 的所有属性并根据 属性 对列表进行排序。但是,如果我有一个 class uitlening,它看起来如下:

public class Uitlening {
    public Int64 id { get; set; }
    public Exemplaar exemplaar { get; set; }
    public Medewerker medewerker { get; set; }
    public String van { get; set; }
    public String tot { get; set; }
}

它包含两个子classes,Exemplaar 和 Medewerker。我的函数只循环 Uitlening 的属性,而不循环 Exemplaar 和 Medewerker 的属性。

如何从子 classes 中获取 'sub-properties' 以循环遍历它并根据它们对我的列表进行排序?

(我想保持我的函数通用,不在其中放置任何 class 相关术语;即

if(prop.Name.Equals("Exemplaar") )

创建一个递归方法,该方法查看属性,然后查看属性的属性,依此类推贯穿对象图。当它命中给定的 属性 名称时,它会停止递归并且 returns 匹配的 属性 值的 ToString()。

然后进行排序。

虽然您试图实现的目标有潜在的危险:您可能会受到意想不到的打击,因此尽管您正在尝试制定一个适用于任何事物的解决方案,但要确保它有效,您需要一些先验知识属性的名称一直向下,这意味着它并没有真正按照您的意愿行事。

您可以告诉您的递归方法仅递归参数中提供的某些类型的属性,或者那些实现给定接口或从给定基础继承的属性 class。如果您确定不会收到任何误报(仅根据名称),您可以默认反对。

我尝试了很多东西并创建了以下通用方法来对子classes 进行排序:

    public static void SortList<T>(ref List<T> list, String sortExpression, SortDirection sortDirection) {
        PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression);
        if (propertyInfo != null) {
            if (sortDirection == SortDirection.Ascending) {
                list.Sort(delegate(T t1, T t2) { return propertyInfo.GetValue(t1).ToString().CompareTo(propertyInfo.GetValue(t2).ToString()); });
            } else {
                list.Sort(delegate(T t1, T t2) { return propertyInfo.GetValue(t2).ToString().CompareTo(propertyInfo.GetValue(t1).ToString()); });
            }
            return;
        } else {
            foreach (var props in typeof(T).GetProperties()) {
                PropertyInfo pro = props.PropertyType.GetProperty(sortExpression);
                if (pro != null) {
                    if (pro.Name.Equals(sortExpression)) {
                        if (sortDirection == SortDirection.Ascending) {
                            list.Sort(delegate(T t1, T t2) {
                                return pro.GetValue(props.GetValue(t1)).ToString().CompareTo(pro.GetValue(props.GetValue(t2)).ToString());
                            });
                        } else {
                            list.Sort(delegate(T t1, T t2) {
                                return pro.GetValue(props.GetValue(t2)).ToString().CompareTo(pro.GetValue(props.GetValue(t1)).ToString());
                            });
                        }
                        return;
                    }
                }
            }
        }
    }

它基本上是 returns 当找到命中时,所以没有使用不必要的时间。首先它查看第一个 class 层次结构,然后它会查看第二个层次结构。 (当然现在扩展到更多层次结构很简单) 我分享答案,因为如果其他人可能对答案感兴趣或任何人有一些额外的反馈。