Why doesn't "object reference not set to an instance of an object" tell us which object?

  • We're launching a system, and we sometimes get the famous exception NullReferenceException with the message Object reference not set to an instance of an object.

    However, in a method where we have almost 20 objects, having a log which says an object is null, is really of no use at all. It's like telling you, when you are the security agent of a seminar, that a man among 100 attendees is a terrorist. That's really of no use to you at all. You should get more information, if you want to detect which man is the threatening man.

    Likewise, if we want to remove the bug, we do need to know which object is null.

    Now, something has obsessed my mind for several months, and that is:

    Why doesn't .NET give us the name, or at least the type of the object reference, which is null?. Can't it understand the type from reflection or any other source?

    Also, what are the best practices to understand which object is null? Should we always test nullability of objects in these contexts manually and log the result? Is there a better way?

    Update: The exception The system cannot find the file specified has the same nature. You can't find which file, until you attach to the process and debug. I guess these types of exceptions can become more intelligent. Wouldn't it be better if .NET could tell us c:\temp.txt doesn't exist. instead of that general message? As a developer, I vote yes.

    The exception should include a stack trace with line number. I would start my investigation from there looking at every object accessed on that line.

    Also, I've always wondered why the exception helper dialog in Visual Studio includes the "helpful" hint to use `new` to create instances of a class. When does such a hint every really help?

    And what if for any reason, you have 10 objects on that line? Like a RESTful API URL builder, which creates the URL, based on almost 7 input parameters? Still it's not helpful that much. Also, now that I look at logs, I don't see line numbers, I don't know why.

    That is a problem, but, alas, I don't have a better answer. In fact, I've had the same problem myself and that is the best I could come up with. I am curious what other responses your question generates.

    If you have a chain of ten object calls then you've got a problem with coupling in your design.

    I love how every single answer to this question are along the lines of "Use a debugger, log your errors, check for null, it's your fault anyway" which are not answering the question but putting the blame on you. Only on stackoverflow does someone actually give you an answer (which I think says it's too much overhead for the VM to keep track of). But really, the only people who can answer this question properly is someone from microsoft who worked on the framework.

    "Can't it understand the type from reflection". No it can't. The object you'd reflect doesn't exist. This is like saying, "If you're absent, please raise your hand". Similarly, when variable names are not preserved in compiled code it's hard to automatically make them part of exception messages. It's not that I wouldn't love to have what you're asking for. I just know why it doesn't work that way.

    Of course it could easily work as OP asks if we wanted it to, and in debug builds it wouldn't require any new information. One of these days Microsoft or somebody else will do what the OP is suggesting, and then the next generation of programmers will wonder how anybody lived without it, and we'll be left grumbling about "kids these days". It's just a tradition that hasn't changed yet.

  • stijn

    stijn Correct answer

    9 years ago

    The NullReferenceException basically tells you: you are doing it wrong. Nothing more, nothing less. It's not a full-fledged debugging tool, on the contrary. In this case I'd say you're doing it wrong both because

    • there is a NullReferenceException
    • you didn't prevent it in a way you know why/where it happened
    • and also maybe: a method requiring 20 objects seems a bit off

    I'm a big fan of checking everything before things start going wrong, and providing good information to the developer. In short: write checks using ArgumentNullException and the likes and write the name yourself. Here's a sample:

    void Method(string a, SomeObject b)
    {
        if (a == null) throw ArgumentNullException("a");
        if (b == null) throw ArgumentNullException("b");
    
        // See how nice this is, and what peace of mind this provides? As long as
        // nothing modifies a or b you can use them here and be 100% sure they're not
        // null. Should they be when entering the method, at least you know which one
        // is null.
        var c = FetchSomeObject();
        if(c == null)
        {
            throw InvalidOperationException("Fetching B failed!!");
        }
    
        // etc.
    }
    

    You could also look into Code Contracts, it has it quirks but it works pretty well and saves you some typing.

    With a project of more than 1000 methods and functions, and more than 2000 operations (imaginary, but close to real numbers), writing that checking code becomes a tedious task. Not a good solution. But thanks for your answer. :)

    @SaeedNeamati you are not implying that because you have a large codebase you should not do decent error checking, right? Imo the larger the project, the more important become the roles or error checking and reporting.

    No, I'm not implying that. I only say that checking every object to get sure that it's not null, is not a good method. That's all. :)

    +1 for good advice, even if it doesn't answer the actual question (which probably only Anders Hejlsberg can answer).

    +1 for excellent advice. @SaeedNeamati you should listen to this advice. Your problem is caused by carelessness and a lack of professionalism in the code. If you don't have time to write good code, you have much bigger problems...

    If you don't have time to write *good* code, then you definitely don't have time to write *bad* code. Writing bad code takes longer than writing good code. Unless you *really* don't care about bugs. And if you *really* don't care about bugs, why write the program at all?

    @SaeedNeamati `I only say that checking every object to get sure that it's not null, is not a good method` Seriously. It's the best method. And not just null, check every argument for reasonable values. The earlier you catch errors, the easier to find the cause. You don't want to have to backtrack several levels in the stack trace to find the causing call.

    @SaeedNeamati The trick here is to do it from the start. When you write a method with parameters, the first thing you should do before developping the body of the method is to check the validity of these parameters. Just define a code snippet where you only need to fill out the name of the parameter to check if it's null. It is very easy to do and it's definitely the best method. Every one here agrees except you.

    Not opposed to the practice of checking everything beforehand, but by the logic of your first two items, `ArgumentNullException` could also go without any information on *which* argument was illegally `null` whatsoever.

    @O.R.Mapper no the parameter in the ArgumentNullException constructor explicitly tells you which parameter is null;

    @jk.: Exactly - if we followed the logic of the first two items, we could skip that parameter without having any qualms.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM

Tags used