List上的通用排序
我有以下代码:
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
或 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您只需要定义第二个泛型类型,这样您就可以传入
List
和一个单独的比较(我称之为 U):话虽如此,我质疑它的用处。为什么不直接使用标准 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):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.已经有一个
OrderBy
扩展方法。There's already an
OrderBy
extension method.