如何通过对象中的属性对List<T>进行排序

1621
我有一个名为Order的类,它具有诸如OrderIdOrderDateQuantityTotal等属性。我有一个这个Order类的列表:
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

我想根据Order对象的一个属性对列表进行排序;例如,根据OrderDateOrderID进行排序。
在C#中,我该如何实现这个功能?
24个回答

1

我为 List<T> 创建了这个扩展方法。

这个扩展方法将你想要排序的属性作为解析后的字符串传入,然后使用 List<T>OrderBy 方法进行排序。接着将原始列表的每个索引设置为有序列表相同的索引。

public static class ListExtensions {
    public static void SortBy<T>(this List<T> list, string property, bool reverse = false) {
        List<T> ordered = list.OrderBy(obj => obj.GetType().GetProperty(property).GetValue(obj, null)).ToList();
            
        for (int i = 0; i < list.Count; i++)
            list[i] = reverse ? ordered[list.Count - 1 - i] : ordered[i];
    }
}

如果列表中的对象具有属性Name,您可以按以下方式对列表 testList 进行排序:
//For normal sorting order
testList.SortBy("Name");
//For reverse sorting order
testList.SortBy("Name", true);

我建议您将SortBy的名称更改为Prefix_SortBy之类的名称,以防止导入其他库时出现潜在冲突。
我知道这种方法适用于字母和数字排序。它的排序能力可能有限,但非常易于操作。
如果存在一些主要缺陷或问题,请告诉我,我已经编写了约3个月的C#程序。
最好的问候

使用反射来实现这种代码并不是一个好主意。而使用通用选择器函数(x=>x.Name)可以以强类型的方式完成相同的操作。 - mtone

1
  • 如果您需要对问题实体中的字符串Id进行排序

  • 请使用Sort函数并委托解析后排序Id值

    class Question
    {
        public List<QuestionInfo> Questions Info{ get; set; }
    
    }

    class QuestionInfo
    {
        public string Id{ get; set; }
        public string Questions{ get; set; }
    
    }

    var questionnaire = new Question();
     questionnaire.QuestionInfo.Sort((x, y) => int.Parse(x.Id, CultureInfo.CurrentCulture) - int.Parse(y.Id, CultureInfo.CurrentCulture));


0

嗨,回到问题上。 如果您想对此序列的列表进行排序 "1" "10" "100" "200" "2" "20" "3" "30" "300" 并以这种形式获取排序后的项目 1;2;3;10;20;30;100;200;300,您可以使用以下方法:

 public class OrderingAscending : IComparer<String>
    {
        public int Compare(String x, String y)
        {
            Int32.TryParse(x, out var xtmp);
            Int32.TryParse(y, out var ytmp);

            int comparedItem = xtmp.CompareTo(ytmp);
            return comparedItem;
        }
    }

而你可以在代码后台以这种形式使用它:

 IComparer<String> comparerHandle = new OrderingAscending();
 yourList.Sort(comparerHandle);

0
从性能的角度来看,最好使用排序列表,以便在将数据添加到结果时对数据进行排序。 其他方法需要至少在数据上进行一次额外的迭代,并且大多会复制数据,因此不仅会受到性能影响,而且会影响内存使用情况。当元素数量达到数千个时,可能不是一个问题,但在服务中,许多并发请求可能同时进行排序,因此会成为一个问题。 请查看System.Collections.Generic命名空间,并选择具有排序功能的类,而不是List。
如果可能的话,请避免使用反射的通用实现,这也可能导致性能问题。

如何提高性能?将数据插入到已排序的列表中是O(n)的,因此添加n个项目是O(n^2)的。如果有许多并发项目正在尝试添加,该怎么办?在添加项目时可能会有额外的CPU周期可供使用,但这不是一个好的通用解决方案。 - John La Rooy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接