C# List<T> 扩展排序多级函数SortBy

473 阅读1分钟

一、目标

实现像SQL那样select name,sex,age from user order by name asc,sex desc   按 name asc,sex desc 方式对List<T>的公共字段/属性进行多级排序。

public class TestData
{
    public string name;
    public string sex;
    public int age;
}

List<TestData> list=new List<TestData>();
list=list.SortBy("name asc,sex desc");

二、实现

1、使用反射收集需要排序的公共字段或属性和排序类型(升序/降序),若传入的不是公共字段或属性,则跳过。

T row = list[0];
Type type = row.GetType();

//收集需要排序的公共字段或公共属性
List<ListSortByInfo> OrderByInfoList = new List<ListSortByInfo>();
if (!string.IsNullOrEmpty(OrderBy))
{
	string[] OrderBys = OrderBy.Trim().Split(new char[] { ',' });
	for (int ind = 0; ind < OrderBys.Length; ind++)
	{
		string _OrderBy = OrderBys[ind].Trim();
		string sortName = _OrderBy.Split(new char[] { ' ' })[0].Trim();
		string sortOrder = _OrderBy.Replace(sortName + " ", "").Trim().ToLower();
		if (!string.IsNullOrEmpty(sortName) && (type.GetProperty(sortName) != null || type.GetField(sortName) != null))
		{
			OrderByInfoList.Add(new ListSortByInfo
			{
				sortName = sortName,
				sortOrder = sortOrder
			});
		}
	}
}

2、使用List自带的排序方法 OrderBy、OrderByDescending、ThenBy、ThenByDescending  按顺序排序。

//排序处理
if (OrderByInfoList.Count > 0)
{
	//处理第一个排序
	ListSortByInfo sort01 = OrderByInfoList[0];
	var sortData = sort01.sortOrder == "desc" ? list.OrderByDescending(row2 => GetObjectValue(row2, sort01.sortName))
		: list.OrderBy(row2 => GetObjectValue(row2, sort01.sortName));
	if (OrderByInfoList.Count > 1)
	{
		for (int ind = 1; ind < OrderByInfoList.Count; ind++)
		{
			ListSortByInfo sort02 = OrderByInfoList[ind];
			sortData = sort02.sortOrder == "desc" ? sortData.ThenByDescending(row2 => GetObjectValue(row2, sort02.sortName))
				: sortData.ThenBy(row2 => GetObjectValue(row2, sort02.sortName));
		}
	}
	return sortData.ToList();
}

示例代码:github.com/penn6699/So…