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!!
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.