【问题标题】:C# -IComparable<T> and IEquatable<T> [duplicate]C# -IComparable<T> 和 IEquatable<T> [重复]
【发布时间】:2009-11-14 16:31:31
【问题描述】:

可能重复:
What’s the difference between IComparable & IEquatable interfaces?

IComparable&lt;T&gt;IEquatable&lt;T&gt; 之间的主要区别是什么? 什么时候具体使用每一个?

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    IComparable 定义顺序(小于、大于)。它定义的方法是CompareTo,你可以用它来确定两个元素之间的顺序。

    IEquatable 定义相等。它定义的方法是Equals,它可以让你判断两个元素是否相等。

    比较示例,按年龄排序人物

    public class Person : IComparable<Person>
    {
        public int Age { get; set; }
        public int ID { get; set; }
    
        public int CompareTo(Person other)
        {
    
            return Math.Sign(Age - other.Age); // -1 other greater than this
                                               // 0 if same age
                                               // 1 if this greater than other
        }
    }
    

    排序用法:

    [Test]
    public void SortTest()
    {
        var persons = new List<Person>
                          {
                              new Person { Age = 0 },
                              new Person { Age = 2 },
                              new Person { Age = 1 }
                          };
    
        persons.Sort();
    
        Assert.AreEqual(0, persons[0].Age);
        Assert.AreEqual(1, persons[1].Age);
        Assert.AreEqual(2, persons[2].Age);
    }
    

    等式示例,用于通过 ID 识别人员:

    public class Person : IEquatable<Person>
    {
        public int Age { get; set; }
        public int ID { get; set; }
    
        public bool Equals(Person other)
        {
            return ID == other.ID;
        }
    }
    

    【讨论】:

    • 如果你重载了 operator
    • 使用Math.Sign 实现CompareTo 真的很很糟糕。上溢/下溢 FTW。
    【解决方案2】:

    如果您要对 IEnumerable&lt;T&gt;, 进行排序,请在比较两个实例是否相等时使用 IComparable&lt;T&gt;,IEquatable&lt;T&gt;

    【讨论】:

      【解决方案3】:

      通常任何排序都将使用您的类的 IComparable 接口(如果可用),否则 .Net 将应用可能完全出乎意料的默认排序。
      如果您没有定义一个,则将使用默认值 - 在您从 IComparable 继承的情况下,如果某个基类实现了这一点,那么排序顺序将是基类定义的任何内容。

      IEquatable 定义了相等性,并允许您定义 .Net 如何使用 Equals 方法确定您的类的实例是否相等。如果您没有定义一个,则默认情况下相等性基于引用相等性。这意味着除非您将两个引用与一个类的同一个实例进行比较,否则它们将不相等,即使您希望它们相等也是如此。同样,如果您从一个实现了接口的基类继承,而您自己没有在您的类中实现它,您将使用基类相等性计算。

      通常,如果您要结合使用常见的 .Net 功能,那么实现这些功能很重要。例如,如果您在类的集合上使用 Contains() 函数,那么它将尝试使用 IEquatable 接口

      来自 MSDN:

      IEquatable)>) 接口 由通用集合对象使用 比如 Dictionary)>)、List)>) 和 LinkedList)>) 测试时 等方法中的平等 包含、IndexOf、LastIndexOf 和 消除。它应该被实施为 任何可能存储在 通用集合。

      IComparable)>) 接口 提供强类型比较 排序成员的方法 通用集合对象。因为 这个,通常不叫 直接来自开发者代码。反而, 它由方法自动调用 比如列表)>)..::.Sort()()() 和添加

      .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        相关资源
        最近更新 更多