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. 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. 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:
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. Entirely legit, just not something the C# compiler would normally do.
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).
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. Note how I'm using another public method with the right parameter type - I'd implement IEquatable<MyType>
at the same time.