繁体   English   中英

应该是IEquatable <T> 等号()通过IComparable实现 <T> 的CompareTo()?

[英]Should be IEquatable<T>'s Equals() be implemented via IComparable<T>'s CompareTo()?

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

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

  • 对于IEquatable

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

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

所以我一直在想这个:

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

    return CompareTo(other) == 0;
}

我忽略了什么或者这样可以吗?

根据微软C#编译团队的前开发人员Eric Lippert的说法

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

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

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

public int CompareTo(Natural x) { return CompareTo(this, x); }
public static bool operator <(Natural x, Natural y) { return CompareTo(x, y) < 0; }
public static bool operator >(Natural x, Natural y) { return CompareTo(x, y) > 0; }
public static bool operator <=(Natural x, Natural y) { return CompareTo(x, y) <= 0; }
public static bool operator >=(Natural x, Natural y) { return CompareTo(x, y) >= 0; }
public static bool operator ==(Natural x, Natural y) { return CompareTo(x, y) == 0; }
public static bool operator !=(Natural x, Natural y) { return CompareTo(x, y) != 0; } 
public override bool Equals(object obj) { return CompareTo(this, obj as Natural) == 0; }
public bool Equals(Natural x) { return CompareTo(this, x) == 0; }

private static int CompareTo(Natural x, Natural y) { ... }

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

x.CompareTo(y) == 0仅表示在排序元素xy ,项目显示为“在相同位置”

例如,给定以下类:

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,因为他们不是同一个人。

根据IEquatable(T)接口中IEquatable接口应该用于确定两个对象是否相等 根据IComparable(T)接口IComparable接口应该用于支持对象的比较 ,以确定它们的顺序。

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

它总是取决于你如何看待对象本身。 可能是(一个愚蠢的例子,我知道)如果它们具有相同的engine type ,相同的engine power等,则指定两辆车是相同的。 如果您想订购他们,你想也许比较发动机的只是权力,而不是类型和其他一切命令他们。 所以,你可以实现Equals返回true,如果对象本身包含相同的值/引用和CompareTo如果他们也许只有相同的功率,但也许不同的发动机类型,等等。

(旁注:这就是我更喜欢与IComparer(T)接口进行比较的原因。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM