List上的通用排序

发布于 2024-08-19 12:47:28 字数 3294 浏览 6 评论 0原文

我有以下代码:

   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,我想使用相同的方法进行排序。

我尝试用 ListList替换 List 但这不起作用。

有什么想法吗?

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

谢谢

更新:解决方案

好的,根据我的讨论和提供的答案(非常感谢所有回复的人),我找到了一种更简单的方法来做到这一点。

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

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);

再次感谢大家帮助我解决这个问题并向我展示了处理此问题的更好方法。

谢谢!!

I have the following code:

   public class OMyObject
   {
       public int Id { get; set; }
       public string Value { get; set; }
       public DateTime? MyDate  { get; set; }
   }

I also have this code:

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;
    }

}

Now I have a test console app which does the following:

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();

So you can see that I am passing in a property to sort on.

The question is this:

How can I make my Sort() extension method generic to be able to pass in any List object to sort?

So if I created a OMySecondObject, I want to use the same method for sorting.

I tried replacing List<OMyObject> with List<T> or List<object> but that does not work.

Any thoughts?

Let me know if you need further clarification with what I am attempting to do.

Thanks

UPDATE: SOLUTION

Okay based on my discussion and answers provided (thank you very much to everyone who responded) I have figured out an easier way to do this.

I have this method which simulates a database call:

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;
        }

I then just sort this list as follows:

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

Again, thank you everyone for helping me figure this out and showing me the better way of handling this.

THANKS!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋叶绚丽 2024-08-26 12:47:28

您只需要定义第二个泛型类型,这样您就可以传入 List 和一个单独的比较(我称之为 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,但坚持标准通常更易于维护。

You just need to define a second generic type, so you can pass in a List<T> and a separate comparison (which I called 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; 
    } 
} 

That being said, I question the usefulness of this. Why not just use the standard LINQ OrderBy?

OrderBy is slightly different, since this would do sorting in place, and OrderBy returns a new sorted IEnumerable<T>, but sticking to standards is typically more maintainable.

时光倒影 2024-08-26 12:47:28

已经有一个 OrderBy 扩展方法。

There's already an OrderBy extension method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文