Possible Duplicate:
Why check this != null?
// Determines whether two strings match.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public override bool Equals(Object obj)
{
//this is necessary to guard against reverse-pinvokes and
//other callers who do not use the callvirt instruction
if (this == null)
throw new NullReferenceException();
String str = obj as String;
if (str == null)
return false;
if (Object.ReferenceEquals(this, obj))
return true;
return EqualsHelper(this, str);
}
The part I don't understand is the fact that it is checking for the current instance, this
, against null. The comment is a bit confusing, so I was wondering what does that comment actually mean?
Can anyone give an example of how this could break if that check was not there, and does this mean that I should also place that check in my classes?
In C#, Equals(String, String) is a String method. It is used to determine whether two String objects have the same value or not. Basically, it checks for equality. If both strings have the same value, it returns true otherwise returns false.
It is preferable to place string literals on the left-hand side of an equals() or equalsIgnoreCase() method call. This prevents null pointer exceptions from being raised, as a string literal can never be null by definition.
That check is there as a guard against native code that may invoke the function with a null this
pointer. This can't happen in C#, so you don't have to put similar guards in your code. It's quite possible that the String
class was written before C# was finalized and the author might have thought it important to guard against nulls, or maybe it's just common to call String
methods from native code and other places that make it easy to call methods on null.
Note that even if you do manage to get called with a null this
and you don't have the guard, all that will happen is that the exception will be slightly different. It might be a different exception and it might get thrown by a different member, but otherwise it's unlikely to make a difference.
In other words, if the null check wasn't there, the EqualsHelper
(or one of its callees) would throw the exception rather than Equals
. Since it's desirable to hide the internals of the user-visible function, it makes sense to put the check right at the beginning.
The added null check is not only meant for the latter languages but also to aid debuggability to throw at the location where the error (call an instance method of a null object) does occur. If it were not there you can call any method inside the class without any error as long as this is never dereferences (accesses member variables). This can go so far that on your null object several method calls did work and suddenly you get a null reference exception back (the method where instance data was accessed).
If you look at the checks inside the .NET classes it is clear that only on some prominent classes like string do contain such guards. Other methods like IndexOf do not guard against this. This is inconsistent but I do think the performance penalty for such double null checks were not worth the effort because most users of the BCL are languages which uses the callvirt instruction where a second null check does not help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With