如何实现多个CompareTo方法?

时间:2018-12-07 09:30:24

标签: c# generics

我有一个自定义的通用数组/容器,它有一个排序方法:

public void Sort()
{
    for (int i = 0; i < Count; i++)
    {
        int min = i;
        for (int j = i + 1; j < Count; j++)
            if (Items[j].CompareTo(Items[min]) < 0)
                min = j;

        if (min == i) continue;
        T temp = Items[i];
        Items[i] = Items[min];
        Items[min] = temp;
    }
}

Items是T个对象的数组。 T实现IComparable并具有CompareTo方法:

public int CompareTo(object obj)
{
    if (!(obj is Player))
        return -1;

    Player player = (Player)obj;
    if (Name.CompareTo(player.Name) < 0)
        return -1;
    else if (Name.CompareTo(player.Name) == 0)
        return LastName.CompareTo(player.LastName);
    else
        return 1;
}

播放器类具有3个属性:名称,姓氏和分数。 这可以按名称和姓氏对元​​素进行排序,效果很好,但是现在我需要另一个容器,该容器应按score排序(第三个属性)。 如何在不使用List和内置OrderBy,Sort方法的情况下实现两种不同的比较方法?

是否可以通过某种方式将类属性传递给Sort方法?

Container<Player> sortedByName = playerList.Sort(Name, LastName);
Container<Player> sortedByScore = playerList.Sort(Score);

2 个答案:

答案 0 :(得分:7)

请勿使用IComparable。这将创建始终知道使用相同条件进行比较的对象。

实际上,创建一个外部IComparer-两个!一个知道如何按名称比较两个球员,另一个知道如何按分数比较他们。

您可以了解如何将其与标准Sort here结合使用。或者,您可以通过将Sort替换为Items[j].CompareTo(Items[min])

来用在自己的comparer.Compare(Items[j], Items[min])方法中

答案 1 :(得分:2)

您应该实现IComparer<T>。然后,您可以更改您的排序方法以接受它:

public class PlayerNameComparer : IComparer<Player>
{
    public int Compare(Player x, Player y)
    {
        if (x.Name.CompareTo(y.Name) < 0)
            return -1;
        else if (x.Name.CompareTo(y.Name) == 0)
            return x.LastName.CompareTo(y.LastName);
        else
            return 1;
    }
}

以及修改后的Sort方法:

public void Sort(IComparer<Player> comparer)
{
    for (int i = 0; i < Count; i++)
    {
        int min = i;
        for (int j = i + 1; j < Count; j++)
            if (comparer.Compare(Items[j], Items[min]) < 0)
                min = j;

        if (min == i) continue;
        T temp = Items[i];
        Items[i] = Items[min];
        Items[min] = temp;
    }
}

用法示例:

collection.Sort(new PlayerNameComparer());
collection.Sort(new ScoreComparer());