![](/img/trans.png)
[英]Should IEquatable<T>, IComparable<T> be implemented on non-sealed classes?
[英]Should be IEquatable<T>'s Equals() be implemented via IComparable<T>'s CompareTo()?
我一直在寻找互联网上的答案,但我发现的只有:
编辑:添加了一些项目以回答答案
对于IEquatable
Equals()
, GetHashCode()
, ==
和!=
。 !=
via ==
来减少冗余。 对于IComparable
Equals()
, GetHashCode()
, <
, >
, <=
和>=
。 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 <= y
且x.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
仅表示在排序元素x
和y
,项目显示为“在相同位置”
例如,给定以下类:
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.