4

I just found it in dotPeek, String.cs:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[__DynamicallyInvokable]
public override bool Equals(object obj)
{
  if (this == null)
    throw new NullReferenceException();
  string strB = obj as string;
  if (strB == null)
    return false;
  if (object.ReferenceEquals((object) this, obj))
    return true;
  if (this.Length != strB.Length)
    return false;
  else
    return string.EqualsHelper(this, strB);
}

At the second line a NullReferenceException is thrown if this == null. So how does it possible to call method of null object?

MSDN says: Note that applications throw the ArgumentNullException exception rather than the NullReferenceException exception discussed here.

The following Microsoft intermediate language (MSIL) instructions throw NullReferenceException:

callvirt
cpblk
cpobj
initblk
ldelem.<type>
ldelema
ldfld
ldflda
ldind.<type>
ldlen
stelem.<type>
stfld
stind.<type>
throw
unbox

If I get it, exception is thrown before the entry into the method body. Right? So what is need to throw NullReferenceException from method? Does __DynamicallyInvokableAttribute force method to be called bypassing any checks? Or something else?

Thanks.

tukaef
  • 9,074
  • 4
  • 29
  • 45
  • Check this question: http://stackoverflow.com/questions/10625326/this-null-inside-net-instance-method-why-is-that-possible – empi Oct 20 '12 at 06:46
  • Duplicate of http://stackoverflow.com/questions/3143498/why-check-this-null – Amit Mittal Oct 20 '12 at 07:19

1 Answers1

4

C# does use callvirt where you get a NullReferenceException before entering the null object. But since the BCL is made for a plethora of languages they did guard against null objects in some central parts (such as string) which do use the call instruction.

Managed C++ is the most notable user of the call instruction.

This was done to aid debugging a bit (as far as I know) but it is not at all consistent throughout the BCL.

Alois Kraus
  • 13,229
  • 1
  • 38
  • 64