C# 应该是合理的<;T>';s Equals()可以通过IComparable实现<;T>';s CompareTo()?
我一直在互联网上寻找答案,但我发现的是: 编辑:添加一些项目以响应答案C# 应该是合理的<;T>';s Equals()可以通过IComparable实现<;T>';s CompareTo()?,c#,C#,我一直在互联网上寻找答案,但我发现的是: 编辑:添加一些项目以响应答案 对于足够的 我应该重载Equals(),GetHashCode(),==和=在一起 我应该通过实现来减少冗余=通过== 我应该封班 对于IComparable 我应该一起重载Equals(),GetHashCode(),,= 事实上,建议在执行此操作时实现IEquatable 重载IComparable的非泛型版本 CompareTo()==0应表示Equals()==true 所以我一直在想: public b
- 对于足够的
- 我应该重载
,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;
}
我是忽略了什么还是这样可以?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(someone)
返回0,因为他们的姓名相同。因此,它们出现的顺序无关紧要
但是,您希望me.Equals(someone)
返回false,因为它们不是同一个人。根据IEquatable
界面中的说明,应使用确定两个对象是否相等。根据i可比较的
界面应用于支持对象的比较,以确定对象的顺序
当然,您可以像以前一样实现Equals
方法,但这样做会在两个不同的事物之间创建依赖关系。两个对象的相等及其顺序
它总是取决于你如何看待对象本身。这可能是(一个愚蠢的例子,我知道)你指定两辆车是相同的,如果它们有相同的发动机类型
,相同的发动机功率
等等。如果你想订购,你可以通过比较发动机的功率来订购,而不是型号和其他一切。因此,如果对象本身包含相同的值/引用,则可以实现Equals
以返回true;如果对象本身可能只有相同的功率,但可能有不同的引擎类型,则可以实现compare to
,以此类推
(旁注:这就是为什么我更喜欢与之进行比较。),微软C#编译器团队的前开发人员:
- 在C语言中有九种比较方法:
=
=
=
object.Equals(object)
IEquatable.Equals(T)
i可比较。与(T)
- 理想情况下,这些都应该彼此一致。也就是说,如果
为真,则x==y
为假,但x
看看OrangeDog的回答。这是针对Java的,但问题类似。IEqutable用于表示相等,而IComparable用于对对象进行排序。另外,您正在实现的IEquatable和IComparable是否也适用于同一个类?如果是,无论出于何种原因,我不认为重用CompareTo实现相等会有什么问题。相反,x0;} 公共静态布尔运算符=0;} 公共静态布尔运算符==(自然x,自然y){返回CompareTo(x,y)==0;} 公共静态布尔运算符=(自然x,自然y){返回CompareTo(x,y)!=0;} public override bool Equals(object obj){返回CompareTo(这个,obj作为自然对象)==0;} 公共布尔等于(自然x){返回CompareTo(this,x)==0;} 私有静态整数比较(自然x,自然y){…}
意味着Equals()==true
。事实并非总是相反,我不同意CompareTo()==0
可能与Equals()==true
不一样-详细信息请参见我的答案。作为旁注,.Hahaha,你的例子比我的好得多:-“CompareTo()==0
意味着x.CompareTo(y)==0
”那么,只有Java是正确的吗?@Johannes我认为,不管使用哪种语言,它都是不正确的。但老实说,JavaDoc提出的相反的事实很有趣。如果x.Equals(y)==true
并不意味着x.CompareTo(y)==0
,那么我认为类代表的东西不是自然的、本质上可排序的身份(相等),它不应该实现x.Equals(y)
。即使是日历事件这样的事件,似乎天生可以按时间排序,也不应该是可比较的,因为它们没有天生的顺序,因为同时发生的两个事件彼此不相等。如果“排序时,排序在一起的项目彼此不相等”,则排序需要范围上下文,请改用IComparable
。以您自己的示例为例,一个人并非天生可以排序,您是否按IComparer
、年龄、身高、智力、温度或其他方式排序完全是任意的。因此,您的姓名
类完全不适合Person
,相反,您应该使用IComparable
。您的示例不是反例,而是支持我的情况,即通过公共类PersonNameComparer:IComparer
比较0的对象也应该相等。Equals应该测试两个对象是否相等,而不管它们的含义如何(即测试它们的内部字段是否相等)。在您的示例中,Equals不尊重其comIComparable
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) { ... }