在 IEquatable中实施是必要的参考检查
我有一个实现 IEquatable
的类。是否有必要在 Equals()
中进行引用检查,或者是否在框架中进行了处理?
class Foo : IEquatable<Foo>
{
int value;
Bar system;
bool Equals(Foo other)
{
return this == other ||
( value == other.value && system.Equals(other.system) );
}
}
上面的例子中的 this==other
语句是多余的还是必要的?
更新 1
我知道我需要更正代码如下:
bool Equals(Foo other)
{
if( other==null ) { return false; }
if( object.ReferenceEquals(this, other) ) { return true; } //avoid recursion
return value == other.value && system.Equals(other.system);
}
感谢您的回复。
I have a class that imlements IEquatable<T>
. Is it necessary to do a refrence check in Equals()
or is it taken care of in the framework?
class Foo : IEquatable<Foo>
{
int value;
Bar system;
bool Equals(Foo other)
{
return this == other ||
( value == other.value && system.Equals(other.system) );
}
}
In the above example is the this==other
statement superfluous or necessary?
Update 1
I understand I need to correct the code as follows:
bool Equals(Foo other)
{
if( other==null ) { return false; }
if( object.ReferenceEquals(this, other) ) { return true; } //avoid recursion
return value == other.value && system.Equals(other.system);
}
Thanks for the replies.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这通常是一种优化 - 这将是一个奇怪的
Equals
实现,没有它就会失败。因此,我不认为它是必要的 - 但它也没有“在框架中得到照顾”。 I 是一种成本低廉的优化,因此通常值得包含。请注意,如果您还重载
==
,那么您可能应该使用object.ReferenceEquals
来执行这些比较。It's generally an optimization - it would be a strange
Equals
implementation which would fail without it. I would therefore not regard it as necessary - but nor does it it "taken care of in the framework". I's a cheap optimization to achieve, so it's usually worth including.Note that if you're also overloading
==
, then you should probably useobject.ReferenceEquals
to perform these comparisons.当心。我实际上强烈不鼓励这样做,因为如果您想根据
Equals<重载您的
Foo
类型的==
运算符/code> (正如我的经验中通常所做的那样)你会发现自己处于无限递归状态。为了说明我的意思,这里是
==
在Equals
方面的常见实现:也就是说,我完全同意 Jon 的观点认为使用
ReferenceEquals
可能比较合适。Be careful. I would actually strongly discourage this since if you ever want to overload the
==
operator for yourFoo
type in terms ofEquals
(as is usually done in my experience) you'll find yourself with an infinite recursion.To illustrate what I mean, here is a common implementation of
==
in terms ofEquals
:That said, I can wholeheartedly agree with Jon's point that it may be appropriate to use
ReferenceEquals
instead.它不是必要,因为它可能不需要正确性,但框架肯定不会“照顾它”,所以它可能放入,通常是出于性能原因。
一点:如果实现由
EqualityComparer.Default
包装,则如果一个或两个参数为null
,则它不会输入用户代码,因此在这种情况下,它确实会执行某种引用检查措施(如果不是完整的ReferenceEquals(x, y)
)。题外话,您的示例方法中存在几个 null 取消引用问题(
other
可能是null
,this.system
可能是空
)。我会将您的方法编写为如下所示:
}
另外,每当您编写自己的相等比较时,请记住覆盖
GetHashCode
。It's not necessary in the sense that it may not be required for correctness, but the framework certainly does not "take care of it", so it may be useful to put in, typically for performance reasons.
One point: if the implementation is wrapped by
EqualityComparer<T>.Default
, it doesn't enter the user code if one or both of the arguments arenull
, so in that case it does perform some measure of reference checking (if not a fullReferenceEquals(x, y)
).Off-topic, there are several null-dereferencing issues in your sample method (
other
might benull
,this.system
might benull
).I would write your method as something like:
}
Also remember to override
GetHashCode
whenever you write your own equality-comparisons.我认为有必要检查
this == other
,因为你定义了自己的equals
。如果您不希望对其进行指针检查,则可以编写自己的IEquatable
。I think it is necessary to check
this == other
, because you define your ownequals
. If you don't want it to be pointer-checked, you write your ownIEquatable
.IEquatable
是一个接口;实施由实施者决定。由于您正在实现接口,因此您需要对接口定义的所有预期行为负责。
IEquatable<T>
is an interface; the implementation is up to the implementer.Since you are implementing the interface you are responsible for all expected behavior as defined by the interface.
我相信这是必要的。参考检查是比较对象时可以执行的第一个快速步骤。
在您给出的示例中,请务必在访问其值之前检查 other 是否不为 null。
I believe that it's necessary. The reference check is the first, quick step you can perform when comparing objects.
In the example you have given, be sure to check that other is not null before accessing its values.