[英]Why would I ever want to do object.ReferenceEquals(null, this) in Equals override?
Consider the following code that I was reviewing: 请考虑以下我正在审核的代码:
public override bool Equals(object other)
{
return !object.ReferenceEquals(null, this)
&& (object.ReferenceEquals(this, other)
|| ((other is MyType) && this.InternalEquals((MyType)other)));
}
The first line in this code triggered my curiosity. 这段代码的第一行引发了我的好奇心。 Whenever
this
is null, the method should return false. 只要
this
为null,该方法应返回false。 Now I am pretty sure the programmer meant to write !object.ReferenceEquals(other, null)
, to shortcut situations with null
, but he's insistent that this
can be null. 现在我非常确定程序员打算写一个
!object.ReferenceEquals(other, null)
,以使用null
来快捷方式,但他坚持认为this
可以为null。 I'm insistent that it cannot (unless someone uses direct memory manipulation). 我坚持认为它不能(除非有人使用直接内存操作)。 Should we leave it in?
我们应该留下吗?
While I certainly wouldn't normally check this
for nullity, it's possible, without any actual memory nastiness - just a bit of reflection: 虽然我肯定不会正常检查
this
为无效,这是可能的,没有任何实际的内存污秽-只是有点反思:
using System;
public class Test
{
public void CheckThisForNullity()
{
Console.WriteLine("Is this null? {0}", this == null);
}
static void Main(string[] args)
{
var method = typeof(Test).GetMethod("CheckThisForNullity");
var openDelegate = (Action<Test>) Delegate.CreateDelegate(
typeof(Action<Test>), method);
openDelegate(null);
}
}
Alternatively, generate IL which uses call
instead of callvirt
to call an instance method on a null target. 或者,生成IL,它使用
call
而不是callvirt
来调用null目标上的实例方法。 Entirely legit, just not something the C# compiler would normally do. 完全合法,不是C#编译器通常会做的事情。
This has nothing to do with finalization, which is hairy in its own right but in different ways. 这与终结无关,终结本身就是毛茸茸的,但却以不同的方式。 It's possible for a finalizer to run while an instance method is executing if the CLR can prove that you're not going to use any fields in the instance (which I would strongly expect to include the
this
reference). 如果CLR可以证明你不会使用实例中的任何字段 (我强烈希望包含
this
引用) ,那么在实例方法执行时可以运行终结器。
As for the code presented - nope, that looks like it's just a mistake. 至于提供的代码 - 不,这看起来只是一个错误。 I would rewrite it as:
我会把它重写为:
public override bool Equals(object other)
{
return Equals(other as MyType);
}
public bool Equals(MyType other)
{
if (ReferenceEquals(other, null))
{
return false;
}
// Now perform the equality check
}
... assuming that MyType
is a class, not a struct. ...假设
MyType
是一个类,而不是一个结构。 Note how I'm using another public method with the right parameter type - I'd implement IEquatable<MyType>
at the same time. 注意我是如何使用具有正确参数类型的另一个公共方法 - 我同时实现
IEquatable<MyType>
。
C# doesn't normally allow methods to be called on null
. C#通常不允许在
null
上调用方法。 I think that the programmer who wrote that is either coming from a C++ background (where I think methods can be called on null
, as long as they don't access a data member of this
) or writing defensively for special scenarios (such as invocation by reflection, as has already been said). 我认为这是谁写的,程序员无论是从C ++背景的(这里我认为方法可以被称为
null
的,只要他们不访问的数据成员this
)或写防守特殊情况下(如调用通过反思,正如已经说过的那样)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.