List.orderBy 陷入无限循环
List.orderBy is getting stuck in an infinite loop
我有一个 List<Expense> myList
,其中费用包含 2 个字段:decimal Amount
和一个 Status ItemStatus
。状态是 enum {Paid, DueSoon, DueToday, Overdue, Unpaid}
.
我试图按升序或降序对列表进行排序,但是 Status.Unpaid
需要始终以升序或降序出现在最后。
使用 myList.Sort((x, y) => comparer.Compare(x.ItemStatus, y.ItemStatus))
和我的比较器效果很好。
但是,在按 ItemStatus
对列表进行排序后,我还想按 Amount
对列表进行排序。所以我决定使用 myList = myList.OrderBy(x => x.ItemStatus, comparer).ThenBy(x => x.Amount).ToList()
这导致某处出现无限循环。
当我完全删除 .ThenBy()
方法时,无限循环仍然存在。
我在我的比较器中添加了一个静态计数器来尝试调试,OrderBy()
方法在 30 项费用的列表中使用了比较器 90 次 在 进入无限之前循环。
这是我的比较器:
class StatusComparer : IComparer<Status>
{
public bool IsAscending { get; private set; } = true;
public StatusComparer(bool isAscending)
{
IsAscending = isAscending;
}
public int Compare(Status x, Status y)
{
if (IsUnpaid(x)) { return IsAscending? 1 : -1; }
if (IsUnpaid(y)) { return IsAscending ? -1 : 1; }
return x.CompareTo(y);
}
private static bool IsUnpaid(Status status)
{
return status.CompareTo(Status.Unpaid) == 0;
}
}
我做错了什么或者我怎样才能实现我想要做的事情?
提前致谢。
您对 Compare
的实施 不正确
public int Compare(Status x, Status y)
{
if (IsUnpaid(x)) { return IsAscending? 1 : -1; }
if (IsUnpaid(y)) { return IsAscending ? -1 : 1; }
return x.CompareTo(y);
}
想象一下,我们有 IsAscending == true
、IsUnpaid(x) == true
和 IsUnpaid(y) == true
。在这种情况下
x.Compare(y) == 1 // so x > y
y.Compare(x) == 1 // so y > x
这就是为什么 OrderBy
很可能会进入无限循环(如果 x > y
和 y > x
,{x, y}
集合的正确顺序是什么?)。您可能想要
public int Compare(Status x, Status y) {
if (IsUnpaid(x)) {
if (!IsUnpaid(y))
return IsAscending ? -1 : 1; // x is UnPaid, y is Paid
}
else if (IsUnpaid(y)) {
return IsAscending ? 1 : -1; // x is Paid, y is UnPaid
}
// x and y either both Paid or unPaid
// If IsAscending should be taken into account, use it as below:
// return IsAscending ? x.CompareTo(y) : y.CompareTo(x);
return x.CompareTo(y);
}
我有一个 List<Expense> myList
,其中费用包含 2 个字段:decimal Amount
和一个 Status ItemStatus
。状态是 enum {Paid, DueSoon, DueToday, Overdue, Unpaid}
.
我试图按升序或降序对列表进行排序,但是 Status.Unpaid
需要始终以升序或降序出现在最后。
使用 myList.Sort((x, y) => comparer.Compare(x.ItemStatus, y.ItemStatus))
和我的比较器效果很好。
但是,在按 ItemStatus
对列表进行排序后,我还想按 Amount
对列表进行排序。所以我决定使用 myList = myList.OrderBy(x => x.ItemStatus, comparer).ThenBy(x => x.Amount).ToList()
这导致某处出现无限循环。
当我完全删除 .ThenBy()
方法时,无限循环仍然存在。
我在我的比较器中添加了一个静态计数器来尝试调试,OrderBy()
方法在 30 项费用的列表中使用了比较器 90 次 在 进入无限之前循环。
这是我的比较器:
class StatusComparer : IComparer<Status>
{
public bool IsAscending { get; private set; } = true;
public StatusComparer(bool isAscending)
{
IsAscending = isAscending;
}
public int Compare(Status x, Status y)
{
if (IsUnpaid(x)) { return IsAscending? 1 : -1; }
if (IsUnpaid(y)) { return IsAscending ? -1 : 1; }
return x.CompareTo(y);
}
private static bool IsUnpaid(Status status)
{
return status.CompareTo(Status.Unpaid) == 0;
}
}
我做错了什么或者我怎样才能实现我想要做的事情?
提前致谢。
您对 Compare
的实施 不正确
public int Compare(Status x, Status y)
{
if (IsUnpaid(x)) { return IsAscending? 1 : -1; }
if (IsUnpaid(y)) { return IsAscending ? -1 : 1; }
return x.CompareTo(y);
}
想象一下,我们有 IsAscending == true
、IsUnpaid(x) == true
和 IsUnpaid(y) == true
。在这种情况下
x.Compare(y) == 1 // so x > y
y.Compare(x) == 1 // so y > x
这就是为什么 OrderBy
很可能会进入无限循环(如果 x > y
和 y > x
,{x, y}
集合的正确顺序是什么?)。您可能想要
public int Compare(Status x, Status y) {
if (IsUnpaid(x)) {
if (!IsUnpaid(y))
return IsAscending ? -1 : 1; // x is UnPaid, y is Paid
}
else if (IsUnpaid(y)) {
return IsAscending ? 1 : -1; // x is Paid, y is UnPaid
}
// x and y either both Paid or unPaid
// If IsAscending should be taken into account, use it as below:
// return IsAscending ? x.CompareTo(y) : y.CompareTo(x);
return x.CompareTo(y);
}