Monday, March 14, 2011

Is throw null and throw new NullReferenceException() the same?

A few times I have seen the use of 
throw null;
where a more verbosely inclined programmer would have written 
throw new NullReferenceException();
So I set out to find out if these 2 uses indeed are equivalent.
Starting out with the code for our class, the matching generated MSIL and finally the stack trace.
using System;
namespace NullRefernceException
{
 public class Class1
 {
  public void DoSomething()
  {
   throw null;
  }
 }
}
.method public hidebysig instance void  DoSomething() cil managed
{
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  ldnull
  IL_0001:  throw
} // end of method Class1::DoSomething
System.NullReferenceException: Object reference not set to an instance of an object.
   at NullRefernceException.Class1.DoSomething() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1.cs:line 8
   at NullRefernceException.Class1Tests.DoSomething_TestDriveNullReferenceException_ExceptionThrown() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1Tests.cs:line 15

And now for the version of the code that is using throw new NullReferenceException

using System;
namespace NullRefernceException
{
 public class Class1
 {
  public void DoSomething()
  {
   throw new NullReferenceException();
  }
 }
}
.method public hidebysig instance void  DoSomething() cil managed
{
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  newobj     instance void [mscorlib]System.NullReferenceException::.ctor()
  IL_0005:  throw
} // end of method Class1::DoSomething
System.NullReferenceException: Object reference not set to an instance of an object.
   at NullRefernceException.Class1.DoSomething() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1.cs:line 8
   at NullRefernceException.Class1Tests.DoSomething_TestDriveNullReferenceException_ExceptionThrown() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1Tests.cs:line 15


And the test used to drive

using System;
using NUnit.Framework;

namespace NullRefernceException
{
 [TestFixture]
 public class Class1Tests
 {
  [Test]
  public void DoSomething_TestDriveNullReferenceException_ExceptionThrown()
  {
   var class1 = new Class1();
   try
   {
    class1.DoSomething();
   }
   catch (Exception exception)
   {
    Console.WriteLine(exception);
   }
  }
 }
}

So from a stacktrace point of view it does not look like there is a difference but in IL there is a difference.

After going through this exercise in code I flexed my Google Fu powers :) and found more information at this link on Stackoverflow - Why does C# allow you to 'throw null'?

No comments: