【问题标题】:difference between IComparable and IComparer [duplicate]IComparable 和 IComparer 之间的区别 [重复]
【发布时间】:2018-04-24 21:23:23
【问题描述】:

IComparableIComparer 接口有什么区别?有必要一直用Array.Sort()方法使用这个接口吗

【问题讨论】:

  • 你是checkdocumentation吗?
  • IComparable 是不使用 IComparer 即可比较的对象。简单简单。 ;)

标签: c# .net icomparable icomparer


【解决方案1】:

顾名思义,IComparable<T> 读出 我是可比的IComparable<T> 当为T 定义时,您可以比较 当前实例 与另一个相同类型的实例。 IComparer<T> 读出我是一个比较者,我比较IComparer<T> 用于比较T 的任意两个实例,通常在T 实例的范围之外。

至于它们的用途,起初可能会令人困惑。从定义中应该很清楚,因此IComparable<T>(在类T 本身中定义)应该是提供排序逻辑的事实上的标准。 List<T> 等上的默认 Sort 依赖于此。在T 上实现IComparer<T> 无助于定期排序。随后,在T 以外的任何其他类上实现IComparable<T> 几乎没有价值。这个:

class MyClass : IComparable<T>

很少有意义。

另一方面

class T : IComparable<T>
{
    public int CompareTo(T other)
    {
        //....
    }
}

是应该怎么做的。

IComparer&lt;T&gt; 在您需要根据自定义顺序进行排序时很有用,但不是一般规则。例如,在 Person 的某个类中,您可能需要根据年龄对人员进行排序。在这种情况下,您可以这样做:

class Person
{
    public int Age;
}

class AgeComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Age - y.Age;
    }
}

现在AgeComparer 有助于根据Age 对列表进行排序。

var people = new Person[] { new Person { age = 23 }, new Person(){ age = 22 } };
people.Sort(p, new AgeComparer()); //person with age 22 comes first now.

IComparer&lt;T&gt; 上的 T 同样没有意义。

class Person : IComparer<Person>

的确,这可行,但看起来不太好,并且不符合逻辑。

通常你需要的是IComparable&lt;T&gt;。理想情况下,您只能拥有一个IComparable&lt;T&gt;,而多个IComparer&lt;T&gt; 可以根据不同的标准。

IComparer&lt;T&gt;IComparable&lt;T&gt;IEqualityComparer&lt;T&gt;IEquatable&lt;T&gt; 完全相同,它们用于测试相等性而不是比较/排序;一个很好的线程here 我写了完全相同的答案:)

【讨论】:

  • 感谢您的回答。我有一个问题:“class MyClass : IComparable 很少有意义。”为什么不 - 它有什么问题?
  • @BKSpureon 因为IComparable&lt;T&gt; 旨在为T 的实例提供默认 顺序。这不仅是 IComparable 这个名字的意义所在,而且从 IComparables 上的 CompareTo 方法的定义中也很明显。定义是public int CompareTo(T),所以你可以做jon.CompareTo(mark),jon & mark 当然是人。当你写时,class RandomClass : IComparable&lt;SomethingElse&gt;,你的CompareTo 让代码看起来像refrigerator.CompareTo(parrot)。虽然从技术上讲,您可能在某个地方需要它,但 .NET 世界并没有那样做。
  • @BKSpureon .NET 开发人员会感到困惑,这不是常态。如果您需要,您可以在一个适当的类中拥​​有一个静态方法(可能是一个扩展方法),上面写着public int Compare(Refrigerator r, Parrot p)
  • 我不认为它会起作用 -people.Sort(p, new AgeComparer());而是 Array.Sort(people ,new AgeComparer())
【解决方案2】:
  • IComparable - 使用 CompareTo() 方法为对象定义一个接口,该方法采用另一个相同类型的对象并将当前对象与传递的对象进行比较。它将比较内化到对象,允许更内联的比较操作,并且在只有一种逻辑方式或绝大多数常见的默认方式来比较某个类型的对象时很有用。
  • IComparer - 使用 Compare() 方法定义一个接口,该方法采用另一种类型的两个对象(不必实现 IComparable)并比较它们。这将比较外部化,当有许多可行的方法来比较一个类型的两个对象时,或者当该类型没有实现 IComparable(或者 IComparable 实现的比较方式与您想要的不同)并且您没有时,这很有用可以控制该类型的来源。

【讨论】:

【解决方案3】:

我读过的最好的解释是“要排序的对象将实现 IComparable,而要对对象进行排序的类将实现 IComparer。” (source)

如果您尝试排序的对象未实现 IComparable,则需要创建一个实现 IComparer 的类(并接受这些对象类型进行比较)并将其传递给 Array.Sort() 方法。

【讨论】:

    【解决方案4】:

    IComparable 用于为您的对象提供默认排序顺序。

    IComparer 是提供额外的比较机制。

    请参阅这篇文章以供参考。 http://support.microsoft.com/kb/320727

    【讨论】:

      【解决方案5】:

      IComparer 比较它给出的两个对象。 IComparable 由正在比较的对象实现,目的是与自身的另一个对象进行比较。

      实现 IComparable 对对象进行排序是个好主意。 IComparable 可用于按不同标准进行排序(例如,按对象中的可选字段进行排序)。

      另见:When to use IComparable<T> Vs. IComparer<T>

      【讨论】:

        【解决方案6】:

        作为实现IComparable 的类的实例的对象可以与其他对象进行比较。 (将IComparable 读作“我可以被比较”。)此接口上执行此操作的方法是CompareTo。如果您希望此类类的实例知道如何将自己与其他对象进行比较,这将非常有用。

        作为实现IComparer 的类的实例的对象可用于比较对象对。 (将IComparer 读作“我可以比较”。)此接口上执行此操作的方法是Compare。如果您想将比较逻辑与被比较的对象类分离,这很有用。如果您有多种比较对象的方法(不区分大小写与区分大小写的字符串比较),您可能会使用这种情况。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-16
          • 2011-04-08
          • 2012-11-24
          • 2013-06-05
          • 2021-09-29
          • 2020-05-27
          • 2016-03-23
          • 2012-08-11
          相关资源
          最近更新 更多