【问题标题】:List<T> Sort uses Comparer<T> instead of IEquatable, Why?List<T> 排序使用的是 Comparer<T> 而不是 IEquatable,为什么?
【发布时间】:2011-05-26 12:39:03
【问题描述】:

我写了一大堆对象,它们都是集合的一部分,我需要对它们进行大量的排序和搜索。在大多数这些对象上,我已经实现并覆盖了Equals 方法、IEquatableoperator!operator==

现在我想在已实现上述所有内容的对象上使用List&lt;T&gt;.Sort,结果我需要实现IComparable 来进行自定义排序。

为什么 Sort 使用 IComparable,那么在我的所有对象中使用 IEquatable 有什么意义?

还有Object.Equal 覆盖与这一切有什么关系?

【问题讨论】:

  • 思想实验;你有三个整数,abc;你知道a==ba!=cb!=c(这是所有可用的组合)。现在:将abc按升序排列;p

标签: .net sorting collections equality


【解决方案1】:

它不可能使用IEquatable&lt;T&gt; 进行排序 - 知道两个事物是否相等并不能帮助您对它们进行排名。但是,如果您的类型实现它,它可以使用IComparable&lt;T&gt;,或者任何IComparer&lt;T&gt;(包括Comparer&lt;T&gt;.Default)来提供自定义比较器对象。函数式风格 (Comparison&lt;T&gt;) 也很方便,无需大量代码即可进行临时排序:

list.Sort((x,y) => string.Compare(x.Name, y.Name));

但如果你只想要一个简单的序数排序,让你的T实现IComparable&lt;T&gt;,然后使用:

list.Sort();

【讨论】:

    【解决方案2】:

    平等只能给你两个对象是否相等的结果。它无法告诉您x 应该在排序顺序中位于y 之前还是之后。仅给定相等性,您如何建议List&lt;T&gt; 应该执行任何排序?

    实现IEquatable&lt;T&gt; 的意义在于当它是重要的平等时,例如在HashSet&lt;T&gt; 中或作为Dictionary&lt;TKey, TValue&gt; 中的键类型。同样,那些不能使用 only IComparable&lt;T&gt; 有效地实现,因为它不会提供哈希码。

    这两个接口基本上用在不同的情况下。

    【讨论】:

      【解决方案3】:

      因为IComparable 允许确定一个对象是否比另一个对象“更小”或“更大”,而IEquatable 有助于确定两个对象是否“相等”。

      排序需要前者,因为仅仅知道哪些对象具有相同的价值并不能帮助您将它们按特定顺序排列。

      【讨论】:

        【解决方案4】:

        因为排序不仅依赖于相等性,还依赖于相对排名。为了排序,您需要知道对象相对于彼此的位置。大于、小于、等于。

        【讨论】:

          【解决方案5】:

          嗯,正如您在 the other questions about this topic 中看到的那样,IEquatable&lt;T&gt; 检查是否相等,而 IComparable&lt;T&gt; 引入了排序所需的等级。

          【讨论】:

            【解决方案6】:

            使用IEquatable 接口,您可以定义一个equivalence relation,但对于排序,您需要一个ordering

            【讨论】:

              【解决方案7】:

              Equality 告诉你两个实例是否相等。可比性告诉您如何对它们进行排序。

              当您比运行时更了解相等性如何适用于您的类型时,您会覆盖 Object.Equals 的实例版本。

              引用类型的相等性默认为引用相等(相同的引用是相同的对象)。

              object o1 = new object();
              object o2 = o1;
              
              if(o2==o1)
              {
                  Console.WriteLine("These reference types are equal");
              }
              
              object o3 = new object();
              
              if(o2 != o3)
              {
                  Console.WriteLine("These reference types are not equal");
              }
              

              值类型的默认相等意味着所有成员变量都相等。您通常应该为值类型覆盖 Equals,因为您可能会更好地了解 equals 的含义。

              这对可比性的影响在于,可比性在某种程度上确实依赖于相等性。为了知道小于或大于的含义,您需要知道等于的含义。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-02-10
                • 1970-01-01
                • 1970-01-01
                • 2020-09-19
                • 2019-04-14
                • 2010-10-14
                • 2011-05-12
                相关资源
                最近更新 更多