General sorting by list <T>

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 application that 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 a property for sorting.

The question arises:

How can I create a general Sort () extension method to be able to pass any List object for sorting?

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

I tried replacing List<OMyObject> with List<T> or List<object> , but that didn't work.

Any thoughts?

Let me know if you need to clarify what I'm trying to do.

thanks

UPDATE: SOLUTION

Well, based on my discussion and answers (thanks to everyone who answered), I figured out an easier way to do this.

I have this method that mimics 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; } 

Then I just sort this list as follows:

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

Again, thanks to everyone for helping me figure this out and show me the best way to handle this.

THANKS!!

+4
source share
2 answers

You just need to define a second generic type, so you can pass 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; } } 

Speaking of this, I doubt the usefulness of this. Why not just use the standard LINQ OrderBy ?

OrderBy is a little different since it will do the sorting in place, and OrderBy returns a new sorted IEnumerable<T> , but adhering to standards is generally more convenient.

+10
source

There is already an OrderBy extension method.

+6
source

Source: https://habr.com/ru/post/1299568/


All Articles