【问题标题】:How to implement multiple CompareTo methods?如何实现多个 CompareTo 方法?
【发布时间】:2018-12-07 09:30:24
【问题描述】:

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

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;
}

Player 类有 3 个属性:Name、LastName 和 Score。 这可以很好地按名称和姓氏对元​​素进行排序,但现在我需要另一个应该按分数排序的容器(第三个属性)。 如何实现两种不同的比较方法不使用 List 和内置的 OrderBy、Sort 方法

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

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

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    不要使用IComparable。这将创建知道如何比较自己的对象,始终使用相同的标准。

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

    您可以查看如何将其与标准 Sort here 一起使用。或者你可以把它用在你自己的Sort方法中,用comparer.Compare(Items[j], Items[min])替换Items[j].CompareTo(Items[min])

    【讨论】:

      【解决方案2】:

      您应该实现IComparer&lt;T&gt;。然后您可以更改您的排序方法以接受它:

      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());
      

      【讨论】:

      • 这是否意味着我必须为每个比较创建一个新类?有没有办法在单个 PlayerComparer 类中完成所有这些操作?
      • 您可以在构造比较器时接受“模式”参数(例如枚举),并根据需要计算比较结果。
      • 还有另一种可能性,正如Sort 页面所暗示的那样:委托(与IComparer 的想法基本相同,只是更紧凑)。
      猜你喜欢
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多