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:Alternatively, generate IL which uses
call
instead ofcallvirt
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:
... assuming that
MyType
is a class, not a struct. Note how I'm using another public method with the right parameter type - I'd implementIEquatable<MyType>
at the same time.