列表<t> </t>上的通用排序

时间:2010-01-27 17:02:44

标签: c# generics extension-methods

我有以下代码:

   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()扩展方法通用,以便能够传入任何List对象进行排序?

因此,如果我创建了一个OMySecondObject,我想使用相同的方法进行排序。

我尝试用List<OMyObject>List<T>替换List<object>,但这不起作用。

有什么想法吗?

如果您需要进一步澄清我想要做的事情,请告诉我。

由于

更新:解决方案

好的,基于我提供的讨论和答案(非常感谢所有回复的人)我已经找到了一种更简单的方法。

我有这个模拟数据库调用的方法:

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 个答案:

答案 0 :(得分: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>,但坚持标准通常更易于维护。

答案 1 :(得分:6)

已有OrderBy扩展方法。