是否需要覆盖==和!=重写Equals方法时的运算符?(.NET)
或者这样做是明智的?是否需要覆盖==和!=重写Equals方法时的运算符?(.NET),.net,operators,overriding,equals-operator,.net,Operators,Overriding,Equals Operator,或者这样做是明智的? 为什么?如果您正在重写equals方法,并且仍然希望能够检查相等(或不相等),那么您可能应该重写==和!=方法也一样。这不是必要的,但却是明智的做法 如果您正在创建一个框架,并且您以外的其他开发人员将使用该对象,那么您应该覆盖==和!=。这样,当开发人员可以使用它时,他们至少有正确的逻辑来比较这两个对象,而不仅仅是在内存中相同 我将确保您的==&!=一定要调用equals方法。请参阅 对于值类型(结构)“Implement==任何时候重写Equals方法” 对于引用类型(类
为什么?如果您正在重写equals方法,并且仍然希望能够检查相等(或不相等),那么您可能应该重写==和!=方法也一样。这不是必要的,但却是明智的做法 如果您正在创建一个框架,并且您以外的其他开发人员将使用该对象,那么您应该覆盖==和!=。这样,当开发人员可以使用它时,他们至少有正确的逻辑来比较这两个对象,而不仅仅是在内存中相同 我将确保您的==&!=一定要调用equals方法。请参阅 对于值类型(结构)“Implement==任何时候重写Equals方法”
对于引用类型(类),“大多数引用类型,即使是实现Equals方法的引用类型,也不应重写==”。不可变类和具有类似值语义的引用类型除外。建议这样做,因为如果:
if (foo == bar)
…表现不同于:
if (foo.Equals(bar))
没有必要,如果你不这样做,没有人会杀了你 但是,请注意,写(A==B)通常比写A.Equals(B)更自然。如果您同时提供这两种方法,代码使用者将更容易使用。请参阅 引述: 默认情况下,运算符==通过确定两个引用是否指示同一对象来测试引用相等性。因此,引用类型不必实现运算符==以获得此功能。当类型是不可变的,即实例中包含的数据无法更改时,重载运算符==以比较值相等而不是引用相等可能很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的。在非不变类型中重写运算符==不是一个好主意 基本上:
如果您想要==和!=表现得像
等于(..)
和!等于(..)
您需要实现运算符。通常只对不可变类型执行此操作。除了这里已经给出的所有答案之外,不要忘记确保GetHashCode()
也一致。在A.Equals(B)中,A不能为null
在A==B中,要么可以为null重写==使其调用等于对引用类型来说通常是个坏主意。如果重写==使其调用Equals,那么我认为代码用户没有办法测试两个对象引用是否引用了完全相同的对象(而不是具有相同属性的对象)
如果人们想测试类实例的值相等性,那么他们当然应该调用Equals,保存==以专门测试引用相等性。您可以使用
Object.ReferenceEquals
来专门检查引用相等性。虽然可以使用Object.ReferenceEquals
,但它相当笨拙。我认为C#使用==
标记进行重载相等测试和引用相等测试操作符是语言中最大的设计错误之一。在许多情况下,foo==bar
的行为与foo.Equals(bar)
不同。错误地相信它们的等价性比认识到它们不能总是表现相同,不应该期望它们表现相同更容易造成麻烦[事实上,框架在等于的意思上存在一些不一致之处,这是由于IMHO错误地希望使其匹配=
]@supercat一个很好的例子是,在比较可为null的类型时,Equals是智能的,并检查每边的HasValue。@Gary:我想的更多的是像Decimal
。有一种比较方法是很有用的,如果两个对象的排名都不高于另一个,那么这种比较方法可以将排名相同的对象(例如1.0d和1.00d)视为不同的,但有一种平等性测试方法也是很有用的。这样的对象应该产生与=
和.Equals
相反的比较结果。