C#首先按类类型排序,然后使用CompareTo

本文关键字:然后 CompareTo 排序 类型 | 更新日期: 2023-09-27 17:59:12

我有一个名为Time的抽象类,然后是两个子类SingleYearPeriod。稍后我可以有更多的子类。

Time类实现了IComparable,但CompareTo函数实际上是在每个子类中实现的。

我在linq中有一个查询,如下所示:myListOfObjects.OrderBy(o=>o.Time);

这是有效的。但是,我希望能够选择SingleYear还是Period对象应该放在第一位(在实际的CompareTo之前)。我对CompareTo的实现是正确的,但在某些情况下,我需要先显示周期,然后显示单年(反之亦然)。

既然我可以有更多的(比方说5-6个)子类,我如何能够指定哪些子类应该先出现,然后CompareTo将在之后完成它的工作?

C#首先按类类型排序,然后使用CompareTo

.OrderBy(o => o is SingleYear).ThenBy(o => o.Time);

在大多数情况下,拥有类和子类的意义在于,我们可以将它们强制转换为基类(或接口),而不再需要区分特定类型。

如果你以一种知道类型的方式对它们进行排序,并且你有五到六种类型,那么你最终会得到这样的结果:

.OrderBy(o => o is SingleYear)
    .ThenBy(o => o is Period)
    .ThenBy(o => o is SomeOtherClass)
    .ThenBy(o => o is Another)
    .ThenBy(o => o is Whatever)
    .ThenBy(o => o is Etc)
    .ThenBy(o => o.Time);

这不是世界末日,但我不喜欢。如果我们不区分代码中的类(检查它们是什么类型)会更好。相反,类通过不同地实现属性和方法来区分本身

排序顺序取决于周期的长度吗?你可以让你的类实现一个指示周期长度的属性——也许这对SingleYear来说是常数,但对Period来说是计算出来的。

然后,您可以在每个类上实现IComparable,也可以提供单独的IComparer<T>实现,如

public class TimeComparer : IComparer<Time>
{
    public int Compare(Time t1, Time t2)
    {
        var periodComparison = t1.Duration.CompareTo(t2.Duration);
        return periodComparison != 0 ? periodComparison : t1.Time.CompareTo(t2.Time);
    }
}

我认为这可以做到:

list.OrderBy(t => typeof(t).Name).ThenBy(o => o.Time)