Generic Sorting on 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 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 answ开发者_如何学JAVAers 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!!
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.
There's already an OrderBy
extension method.
精彩评论