C# 为什么我要在Equals覆盖中执行object.ReferenceEquals(null,this)?
考虑我正在审查的以下代码:C# 为什么我要在Equals覆盖中执行object.ReferenceEquals(null,this)?,c#,.net,null,this,referenceequals,C#,.net,Null,This,Referenceequals,考虑我正在审查的以下代码: public override bool Equals(object other) { return !object.ReferenceEquals(null, this) && (object.ReferenceEquals(this, other) || ((other is MyType) && this.InternalEquals((MyType)other))); } 这
public override bool Equals(object other)
{
return !object.ReferenceEquals(null, this)
&& (object.ReferenceEquals(this, other)
|| ((other is MyType) && this.InternalEquals((MyType)other)));
}
这段代码的第一行引起了我的好奇心。每当
此
为null时,该方法应返回false。现在我很确定程序员是想写!object.ReferenceEquals(other,null)
,指向带有null
的快捷方式,但他坚持认为此
可以为null。我坚持认为它不能(除非有人使用直接内存操作)。我们应该把它放在里面吗?虽然我通常不会检查这个
是否为空,但这是可能的,没有任何实际的内存污点-只是一点反射:
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);
}
}
。。。假设
MyType
是一个类,而不是一个结构。请注意,我是如何使用另一个具有正确参数类型的公共方法的-我将同时实现IEquatable
。C#通常不允许对null
调用方法。我认为编写程序的程序员要么来自C++背景(我认为方法可以在代码< > NUL/<代码>上调用,只要他们不访问<代码> > <代码>的数据成员),或者为特殊场景(如已经说过的调用调用)进行防御编写。ReferenceEquals
的参数顺序无关紧要。你提议的改变也一样。@AndrewBarber:是的,它可以。您需要做一些工作,但是可以调用一个实例方法,其中this
为空。@Abel:噢,这与终结无关。在方法运行时,可以最终确定对象,甚至可以对其进行GC,但如果要在任何地方使用this
,则不能这样做。!ReferenceEquals(null,this)
等同于true
true&&anything
等同于anything
。删除这个条件是安全的。@Ginosaji:讨论是(请参阅其他评论,特别是Jon Skeet的评论,看你的陈述是否真实。似乎并非总是如此;)我想指出,实际问题是我们是否应该保留它?
,而你还没有真正解决这个问题。@Servy,我想乔恩在他的开场白中说过:他不会这么做。相对简单(讨厌?)的把戏,我应该自己想出。如果我必须对此加以防范,我在每个实例方法中都会得到与每个扩展方法中相同的代码:检查空性。添加典型的相等模式也很好,更新很棒!一条评论,如果我错了,请纠正我:我认为GC不会分析代码来证明引用不再被使用(在正在运行的方法中)。我相信这是JIT所做的事情(当然是为了帮助GC的运行)。@TheodorosChatzigiannakis:为了安全起见,编辑为“CLR:)
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
}