应该是IEquatable <t>的Equals()是通过IComparable <t>的CompareTo()实现的吗?

时间:2015-05-16 13:42:35

标签: c#

我一直在互联网上寻找答案,但我发现的只有:

编辑:添加了一些项目以回应答案

  • 对于IEquatable

    • 我应该一起重载Equals()GetHashCode()==!=
    • 我应该通过!=实施==来减少冗余。
    • 我应该密封班级
  • 对于IComparable

    • 我应该将Equals()GetHashCode()<><=>=重叠在一起。
    • 事实上,建议在执行此操作时实施IEquatable
    • 重载非通用版本的IComparable
    • CompareTo() == 0应该是Equals() == true

所以我一直在想这个:

public bool Equals(T other)
{
    if ((object)other == null)
    {
        return false;
    }

    return CompareTo(other) == 0;
}

我是否忽视了某些事情或者这样做了吗?

3 个答案:

答案 0 :(得分:8)

x.CompareTo(y) == 0并不意味着x.Equals(y) == true

x.CompareTo(y) == 0仅表示在排序元素xy时,项目显示为"in the same position"

例如,给定以下类:

public class Person
{
    public string Name { get; set;}
    public string Passport { get; set; }
}

var me = new Person { Name = "Diogo Castro", Passport = "12345" };
var someoneElse = new Person { Name = "Diogo Castro", Passport = "67890" }; 

按名称(按字母顺序)对这两个人进行排序时,您希望me.CompareTo(someoneElse)返回0,因为它们共享相同的名称。因此,它们出现的顺序无关紧要。

但是,您希望me.Equals(someoneElse)返回false,因为他们不是同一个人。

答案 1 :(得分:8)

According to Eric Lippert,微软C#编译团队的前开发人员:

  
      
  • 在C#中有九种方法进行比较:< <= > >= == != object.Equals(object) { {1}} IEquatable<T>.Equals(T)
  •   
  • 理想情况下,这些都应该彼此一致。也就是说,如果IComparable<T>.CompareTo(T)为真,则x == y为false,但x < yx <= y为真且x.Equals(y)为零,依此类推。
  •   

因此,在他看来,“理想情况下”x.CompareTo(y)暗示x.CompareTo(y) == 0,反之亦然。

然后,Eric提供了一个使用私有帮助器方法实现所有内容的示例:

x.Equals(y) == true

答案 2 :(得分:1)

根据IEquatable(T) Interface中的注释,应使用 IEquatable界面来确定两个对象是否相等。根据{{​​3}}, IComparable界面应该用于支持对象的比较,以确定它们的顺序。

当然,您可以像实现自己的Equals方法一样实现,但这样做可以在两个不同的事物之间创建依赖关系。两个对象的相等性及其顺序。

它总是取决于你如何看待对象本身。可能是(一个愚蠢的例子,我知道)如果它们具有相同的engine type,相同的engine power等,则指定两辆车是相同的。如果您想订购它们,您可以通过比较引擎的功能来订购它们,而不是类型和其他所有内容。因此,如果对象本身包含相同的值/引用,则可以实现Equals以及CompareTo,如果它们可能只有 相同的功率但可能是不同的引擎类型等。

(旁注:这就是为什么我更愿意与IComparable(T) Interface进行比较。)