List<T>的通用排序

4
我有以下代码:
   public class OMyObject
   {
       public int Id { get; set; }
       public string Value { get; set; }
       public DateTime? MyDate  { get; set; }
   }

我也有这段代码:
public static class ObjectExtension
{
    public static List<OMyObject> Sort<T>(this List<OMyObject> o, Func<OMyObject, T> keySort, ESortDirection direction) where T : IComparable
    {
        if (direction == ESortDirection.asc)
        {
            o.Sort((a, b) => keySort(a).CompareTo(keySort(b)));
        }
        else
        {
            o.Sort((a, b) => keySort(b).CompareTo(keySort(a)));
        }
        return o;
    }

}

现在我有一个测试控制台应用程序,它执行以下操作:

var myObjectList = new List<OMyObject>
                               {
                                   new OMyObject {Id = 4, MyDate = DateTime.Now.AddDays(4), Value = "Test 4"},
                                   new OMyObject {Id = 2, MyDate = DateTime.Now.AddDays(2), Value = "Test 2"},
                                   new OMyObject {Id = 1, MyDate = DateTime.Now.AddDays(1), Value = "Test 1"},
                                   new OMyObject {Id = 3, MyDate = DateTime.Now.AddDays(3), Value = "Test 3"},

                               };


        Console.WriteLine("Sort By Nullable Date ASC");

        myObjectList.Sort(id => (DateTime)id.MyDate, ESortDirection.asc);

        foreach (var item in myObjectList)
        {
            Console.WriteLine(item.Id + " - " + item.MyDate + " - " + item.Value);
        }
        Console.WriteLine("Sort By ID DESC");
        myObjectList.Sort(id => id.Id, ESortDirection.desc);

        foreach (var item in myObjectList)
        {
            Console.WriteLine(item.Id + " - " + item.MyDate + " - " + item.Value);
        }

        Console.ReadLine();

所以你可以看到我正在传递一个属性来排序。
问题是:
如何使我的Sort()扩展方法通用,以便能够传递任何列表对象进行排序?
因此,如果我创建了OMySecondObject,则希望使用相同的方法进行排序。
我尝试用List<T>或List<object>替换List<OMyObject>,但那样不起作用。
有什么想法吗?
如果您需要进一步澄清我正在尝试做什么,请告诉我。
谢谢
更新:解决方案
好的,基于我的讨论和提供的答案(非常感谢回答的每个人),我已经找到了更简单的方法来做到这一点。
我有这个模拟数据库调用的方法:
public static IEnumerable<OMyObject> GetObject()
        {
            var myObjectList = new List<OMyObject>
                                   {
                                       new OMyObject {Id = 4, MyDate = DateTime.Now.AddDays(4), Value = "Test 4"},
                                       new OMyObject {Id = 2, MyDate = DateTime.Now.AddDays(2), Value = "Test 2"},
                                       new OMyObject {Id = 1, MyDate = DateTime.Now.AddDays(1), Value = "Test 1"},
                                       new OMyObject {Id = 3, MyDate = DateTime.Now.AddDays(3), Value = "Test 3"},

                                   };
            return myObjectList;
        }

然后我按照以下方式对这个列表进行排序:

    IEnumerable<OMyObject> myObjectList = GetObject();
    myObjectList = myObjectList.OrderBy(id => id.MyDate);

再次感谢大家帮助我解决问题并展示更好的处理方式。

谢谢!

2个回答

10

您只需要定义第二个泛型类型,这样您就可以传递一个List<T>和一个单独的比较(我称之为U):

public static class ObjectExtension 
{ 
    public static List<T> Sort<T,U>(this List<T> o, Func<T, U> keySort, ESortDirection direction) where U : IComparable 
    { 
        if (direction == ESortDirection.asc) 
        { 
            o.Sort((a, b) => keySort(a).CompareTo(keySort(b))); 
        } 
        else 
        { 
            o.Sort((a, b) => keySort(b).CompareTo(keySort(a))); 
        } 
        return o; 
    } 
} 

说实话,我对此的有用性表示怀疑。为什么不直接使用标准的LINQ OrderBy呢?
OrderBy略有不同,因为它会就地排序,而OrderBy返回一个新的已排序的IEnumerable<T>,但遵循标准通常更易于维护。

谢谢您提供的信息,这个方法非常有效。我这么做是因为有不同的业务需求需要根据查询结果对不同的列表进行排序。为了避免每次重新查询数据库,我希望在业务层面上根据用户请求进行排序。其中一些查询非常大,我们的数据库服务器性能并不是最好的(我也无能为力)。 - CodeLikeBeaker
@Jason Heine: 什么? 如果你有一个 List<T>,它是在内存中的,不需要与数据库进行任何交互。 - jason
@Jason,嗯,也许我漏掉了什么。我明白你们在说什么。看起来我所做的可能有些过度了。我会对OrderBy()进行更多的研究。 - CodeLikeBeaker
@Jason Heine:如果你在IQueryable上调用OrderBy,它会访问数据库。如果你在IEnumerable上调用OrderBy,它会在内存中排序(LINQ to SQL vs. LINQ to objects)。 - AaronSieb
我已经采纳了您的建议并找到了更好的解决方法。 我已经更新了我的问题并提供了解决方案。 非常感谢大家的帮助! - CodeLikeBeaker

6

已经有一个 OrderBy 扩展方法。


没错。请看这里:http://stackoverflow.com/questions/2136145/how-to-sort-a-listt-by-double-value - Fitzchak Yitzchaki

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