CompareTo 未产生预期的排序顺序

CompareTo Not Resulting in Expected Sort Order

正在尝试对以下列表进行排序:

public class BusinessEvents : IComparable<BusinessEvent>
{
    public long VersionId {get;set;}
    public EventType EventType {get;set;}
}

排序逻辑如下:

public int CompareTo(BusinessEvent businessEvent)
{
    if (VersionId > businessEvent.VersionId)
    {
        return 1;
    }

    if (VersionId < businessEvent.VersionId)
    {
        return -1;
    }

    if (EventType == EventType.TypeC ||
        EventType == EventType.TypeD ||
        EventType == EventType.TypeE)
    {
        if (businessEvent.EventType == EventType.TypeA ||
            businessEvent.EventType == EventType.TypeB)
        {
            return 1;
        }
    }

    return 0;
}

但是,这个单元测试失败了:

[Test]
public void BusinessEvent_Sort_Correctly_Break_Ties_Multiple()
{
    // arrange
    var event1 = GetEventWithTypeAndVersionId(1, EventType.TypeA);
    var event2 = GetEventWithTypeAndVersionId(1, EventType.TypeD);
    var event3 = GetEventWithTypeAndVersionId(1, EventType.TypeC);
    var event4 = GetEventWithTypeAndVersionId(2, EventType.TypeB);
    var event5 = GetEventWithTypeAndVersionId(2, EventType.TypeE);
    var event6 = GetEventWithTypeAndVersionId(2, EventType.TypeC);
    var events = new List<BusinessEvent> {event4, event2, event5, event6, event3, event1};

    // act
    events = events.OrderBy(c => c).ToList();
        
    // assert
    Assert.AreEqual(EventType.TypeA, events[0].EventType);
    Assert.AreEqual(EventType.TypeD, events[1].EventType);
    Assert.AreEqual(EventType.TypeC, events[2].EventType);
    Assert.AreEqual(EventType.TypeB, events[3].EventType);
    Assert.AreEqual(EventType.TypeE, events[4].EventType);
    Assert.AreEqual(EventType.TypeC, events[5].EventType);
}

第一次断言就失败了。它将 EventType.TypeDVersionId 放在排序列表的第一位,即使我指定 EventType.TypeDEventType.TypeA 之后当 VersionId 匹配时也是如此。

很明显,我误解了 API 提供的内容。我怎样才能得到我预期的结果?

问题是当 this.EventTypeTypeATypeB 时,您还没有 returning -1,你 return 0 那样的话。

您还可以通过使用 int.CompareTo 来处理各种情况来简化此操作。实现自定义比较逻辑的最佳方法是在每个级别上使用标准 CompareTo 并检查 != 0.

public int CompareTo(BusinessEvent businessEvent)
{
    var cmp = VersionId.CompareTo(businessEvent.VersionId);
    if (cmp != 0)
        return cmp;

    cmp = (EventType == EventType.TypeA || EventType == EventType.TypeB ? 0 : 1)
        .CompareTo(
            businessEvent.EventType == EventType.TypeA ||
            businessEvent.EventType == EventType.TypeB ? 0 : 1);

    return cmp;
}

其工作方式是将 TypeATypeB 转换为 0,将其他所有内容转换为 1,然后进行比较。显然 01.

之前排序

您可以通过编写某种将不同 EventType 合并在一起的转换函数来添加更多条件或排序。