使用字符串而不使用Linq对List<T>进行排序

6
有没有一种方法可以使用类似于“Name desc”(与DataTable.DefaultView.Sort相同)的字符串对List进行排序,而不是使用Linq?
我正在尝试用Lists替换DataTables,并且需要它能够执行此操作以与旧代码兼容。
解决方案:
使用V4Vendetta的代码,我能够创建这个扩展方法,测试似乎表明它可以工作。
public static void SortByString<T>(this List<T> list, string sortString)
{
    if (sortString == null) return;

    List<string> SortGroups = sortString.Split(',').ToList();

    for (int i = SortGroups.Count - 1; i >= 0; i--)// sort from the last group first
    {
        string tempColumn = SortGroups[i].Trim().Split(' ')[0];
        bool isAsc = SortGroups[i].Trim().Split(' ').Length > 1 ? SortGroups[i].Trim().Split(' ')[1].ToLower() == "asc" ? true : false : true;

        PropertyInfo propInfo = typeof(T).GetProperty(tempColumn);
        if (propInfo == null) // if null check to make sure its not just a casing issue.
        {
            foreach (PropertyInfo pi in typeof(T).GetProperties())
            {
                if(pi.Name.ToLower() == tempColumn.ToLower())
                {
                    tempColumn = pi.Name;
                    propInfo = typeof(T).GetProperty(tempColumn);
                    break;
                }
            }
        }

        if (propInfo != null)
        {
            Comparison<T> compare = delegate(T a, T b)
            {
                object valueA = isAsc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
                object valueB = isAsc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

                return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
            };

            list.Sort(compare);
        }else{
            throw new IndexOutOfRangeException("Property: '" + tempColumn + "', does not exist in '" + typeof(T).ToString() + "'");
        }


    }
}
5个回答

3

List有一些排序方法,其中一些需要使用Comparison<T>来实现自定义比较和排序。


我尝试了这个并且一路学习。但是我更喜欢上面的解决方案,谢谢。 - g.foley

3
据我所知,这种类型的搜索没有内置支持。因此,您将不得不编写自己的搜索功能。
解析字符串应该不难。如果您有一个类似于“name asc,age desc”的排序字符串,请在逗号(,)处拆分它,并将每个拆分后的部分视为名称和方向。然后,您可以使用类型T上的反射来查找要进行排序的属性,并构建执行所需比较的方法。
请参考此文章以获取示例:http://www.codeproject.com/KB/linq/dynamite_dynamic_sorting.aspx

2

我曾经尝试过类似的东西,也许你需要根据自己的需求进行改进。

private List<Employee> CreateSortList<T>(
                    IEnumerable<Employee> dataSource,
                    string fieldName, SortDirection sortDirection)
    {
        List<Employee> returnList = new List<Employee>();
        returnList.AddRange(dataSource);
        // get property from field name passed
        System.Reflection.PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
        Comparison<Employee> compare = delegate(Employee a, Employee b)
        {
            bool asc = sortDirection == SortDirection.Ascending;
            object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
            object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);
            //comparing the items
            return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
        };
        returnList.Sort(compare);
        return returnList;
    }

您需要传入适当的排序方向以及字段名称,该字段名称应为类的属性(在我的情况下是Employee)

希望这可以帮助您


@g.foley 这有帮助到你吗? - V4Vendetta

0

1
考虑到这个问题标题中的“没有Linq”,这很有趣。 - slumtrimpet
人们常常将LINQ与强类型扩展方法混淆。动态查询库允许您使用字符串对列表进行排序,这可能会很有帮助。 - roufamatic

0
看看专门的集合命名空间。那里应该有一个排序列表。

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