6

I have a very simple check right at the beginning of one of my methods as follows:

public void MyMethod(MyClass thing)
{
    if(thing == null)
        throw new ArgumentNullException("thing");

    //Do other stufff....
}

But I'm getting stacktraces (from Elmah in a production environment) which appears to indicate that the "if(thing == null)" line is throwing a NullReferenceException. The first 2 lines of the stack trace are something like:

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at MyLibrary.BL.AnotherClass.MyMethod(MyClass thing) in C:\Development\MyProject\trunk\MyLibrary.BL\AnotherClass.cs:line 100

MyClass is a fairly simple class with no operator overloads or anything like that, so I'm a bit stumped as to what is throwing the NullReferenceException!

Can anybody suggest scenarios that might cause this?

EDIT: I suspect "thing" might be null, but I really would expect an ArgumentNullException not a NullReferenceException - this is basically what this question is about. Is there maybe something that the framework or Elmah that is changing or mis-reporting the exception - or is the only explanation that the binaries are somehow out of date?

John Saunders
  • 157,405
  • 24
  • 229
  • 388
mutex
  • 6,746
  • 8
  • 41
  • 65
  • The error you posted also shows an `HttpUnhandledException`. Where does that come from, and what does `-->` mean? – Chris Laplante Oct 16 '12 at 00:51
  • If you have just added this check, verify that your site uses up-to-date binaries. To avoid potential problems with overloading, there's always `object.ReferenceEquals`. – Anton Tykhyy Oct 16 '12 at 00:55
  • @SimpleCoder: that's just the first line of the stacktrace from Elmah - I've edited the question to include the next line too. Note line 100 in the source file is the if statement. – mutex Oct 16 '12 at 00:56
  • @AntonTykhyy: Nope, I've looked at this file in our source conotrl and the check has always been in place... which is why I'm so confused. – mutex Oct 16 '12 at 00:59
  • Are you using any sort of AOP framework? Examine the actual IL for this method too. As John says below, it's impossible for `object.ReferenceEquals` (which is what the default == for reference types is equivalent to) to throw. – Anton Tykhyy Oct 16 '12 at 01:03
  • 1
    Rather than depending on what unhandled exceptions are thrown and looking at the messages, _debug_ your application and _verify_ that everything is as you claim it to be. – Jeff Mercado Oct 16 '12 at 01:05
  • Congrats for asking a NullReferenceException-related question which hasn't been closed as a duplicate of @JohnSaunders question http://stackoverflow.com/q/4660142/245183. – Ondrej Tucny Jan 06 '15 at 00:13
  • FYI, see http://stackoverflow.com/questions/27071016/how-can-a-stack-trace-point-to-the-wrong-line-the-return-statement-40-line to see a situation I had where the stack trace was wrong. – John Saunders Jan 06 '15 at 00:16

5 Answers5

4

It is impossible for if (thing == null) to throw a NullReferenceException.

This means that something else is going on. It's time to start using your imagination in conjunction with a firm resolve to ignore the possibility that the if caused a problem.

John Saunders
  • 157,405
  • 24
  • 229
  • 388
  • This is kind of what I was afraid of (and suspected) :) I'm guessing I'll be accepting yours as the answer when I do get to the bottom of it. +1 for now. – mutex Oct 16 '12 at 01:05
  • This is not true, what if MyClass has has public static bool operator ==(MyClass a, MyClass b) { throw new NullReferenceException(); } – Matthew Finlay Oct 16 '12 at 01:11
  • It is, however, impossible for (object)thing == null to throw a NullReferenceException – Matthew Finlay Oct 16 '12 at 01:15
  • 1
    It's not possible to get a `NullReferenceException` with that stack trace. The call to `operator==` would have been on the stack. – John Saunders Oct 16 '12 at 01:17
  • 1
    Accepted as answer; I rebuilt and redeployed the binary and the exception is now as excepted - obviously something went wrong on the last deployment of this site. – mutex Oct 16 '12 at 01:56
  • 2
    The moral of the story: If you get a `NullReferenceException` when executing your code, and the source code indicates that it is not possible to get a `NullReferenceException` in the line indicated in the stack trace, then it's because your source code does not match the binary code you are executing. – John Saunders May 15 '14 at 02:53
2

The if statement can throw a NullReferenceException if MyClass defines the == operator incorrectly e.g.

class MyClass
{
   int A {get;set;}

   public static bool operator ==(MyClass a, MyClass b)
   {
      return a.A == b.A;
   }

   public static bool operator !=(MyClass a, MyClass b)
   {
      return !(a == b);
   } 
}
Matthew Finlay
  • 3,154
  • 1
  • 24
  • 32
1

Looks like the exception is coming from something up the chain that calls MyMethod. MyMethod() is throwing the Exception and nothing above is handling it, so whatever web framework you're in is throwing the HttpUnhandledException.

speakingcode
  • 1,441
  • 12
  • 12
  • Yeah but the OP is asking about the `NullReferenceException` that exception wraps. – Paul Bellora Oct 16 '12 at 00:58
  • Is he passing a null value into myMethod()? If he is, the if statement will evaluate true, and throw that exception. If he isn't, then the if statement will evaluate false, and not throw that exception. Is he _certain_ he isn't passing a null reference to the method and getting the exception as expected? – speakingcode Oct 16 '12 at 01:07
0

I also encountered this impossible situation. It turned out to be due to the use of the as keyword, I have no idea why. I was using the SharpPdf library and had a line of code like this:

var destElement = annotDict.Elements["/Dest"] as PdfName;
if (destElement == null)
{
    continue;
}

If I remove the as PdfName portion, it works. So I now have two levels of checking in my code:

var destElement = annotDict.Elements["/Dest"];

if (destElement == null)
{
    continue;
}

var destElementName = destElement as PdfName;
if (destElementName == null)
{
    continue;
}
Oran Dennison
  • 3,065
  • 25
  • 34
-3

thing is null.

That would cause it.

[EDIT]: Here's the code I tested with:

protected void Button3_Click(object sender, EventArgs e)
{
    MyMethod(null);
}

public void MyMethod(String thing)
{
    if (thing == null)   //  This caused the exception to be thrown.
        throw new Exception("test");

    //Do other stufff....
}
Steve Wellens
  • 20,160
  • 2
  • 24
  • 64
  • 3
    -1: How would `thing == null` cause a `NullReferenceException`? – John Saunders Oct 16 '12 at 01:13
  • It did on my box. I copied and pasted the code. It jumped directly to the the NullReferenceException. Maybe optimization moved the code to one line. Try it and see if you experience the same behavior. (VS 2012). Wait...I'll update my post. – Steve Wellens Oct 16 '12 at 02:02