views:

431

answers:

4

Probably a C# noob question, so don't flame me. I was trying to do this:

if (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null)
{
    // ...
}

But I kept getting a System.NullReferenceException. I thought since it returns a string that I could just check for null and move on. It took me a while to find the right way to do it:

ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["PrimaryConnectionString"];
if (cs != null)
{
    this.Connection.ConnectionString = cs.ConnectionString;
}

So in other instances, like checking a Session object for some value I would do a check for null like this:

if (Session["EmployeeID"] != null)
{
    _EmployeeID = System.Convert.ToInt32(Session["EmployeeID"]);
}

So I just wanted to know how do you know when you can or can't do a check for null?

+3  A: 

Your null reference exception happened in parent object (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"]). Once you check it also, you are fine.

try this:

if ((ConfigurationManager.ConnectionStrings["PrimaryConnectionString"] != null)
&& (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null))
  { etc etc }

Notice that if you use more methods from it, it would be useful to separate these checks.

Josip Medved
If the indexer on `ConnectionStrings` returns `null` when an item isn't present, that's rather inconsistent with `Dictionary`, isn't it? It should throw in that case.
Daniel Earwicker
+9  A: 

Your problem was that you were checking:

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]
        .ConnectionString

for a null pointer.

In actual fact,

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]

was null so that, when you tried to dereference that to get the connection string, that's when you got the exception. Effectively, what you're doing is:

null.ConnectionString

which is problematic.

I tend to either avoid many layers of dereferencing in a single statement or place an exception handler around the whole thing to catch problems at any point.

paxdiablo
I saw Josip's answer first and saw the error of my thinking so I marked his as the answer before I saw these additional answers. I like your answer because it is more clear about dereferencing. However since you have more rep then you know what to do with I am sticking by my original mark.
Breadtruck
That's okay, @Breadtruck. It only takes two upvotes (20) to outdo an accept (15) and, to be honest, most of my rep comes from gradual upvotes of answers I'd forgotten about months ago :-) At some point, the rep gets boring and the true intent of SO comes through (giving the best answers possible for their own sake). Anyway, the chances of me getting into that first column on the users page is diminishing since I also have a real life (wife/kids/dog/etc). The chance of me catching Skeet is zero unless he suffers a serious debilitating illness (I hope not).
paxdiablo
@Everyone : Could I get anyone interested to check out my other question, which led me to this problem in the first place. Like to get more ideas or agreement on best solution. http://stackoverflow.com/questions/1148559"What is preferred method for modifying connection string settings in DAL class library when deploying asp.net web app?"
Breadtruck
+4  A: 

Your first test checks whether the connection string within the ConnectionStringSettings is null. The second test checks whether the ConnectionStringSettings reference itself is null. It's the difference between:

if (person.Name == null)

and

if (person == null)

The first will go bang if person is null; the second won't spot if person.Name is null. If you want to check both, you need:

if (person == null || person.Name == null)

Some languages (such as Groovy) have a null-safe dereferencing operator, so you can do:

var x = Expr1?.Expr2?.Expr3?.Expr4;

That makes this sort of test easier, if you want to test whether any part of a potentially long expression is null. Unfortunately C# doesn't have that :(

Jon Skeet
It would be great if you'd mention an example or two of languages with that null-safe operator, I'm curious! `=)`
Blixt
@Skeet ... I have had my first Skeet sighting ;)
Breadtruck
@Blixt: Have edited to mention Groovy. I'm pretty sure there are others, but I can't think of them offhand...
Jon Skeet
I answered another question with a "chained null check" idea, basically the same concept but unfortunately not very succinct in C# and you may find it *less* readable. http://stackoverflow.com/questions/336775/pipe-forwards-in-c
Daniel Earwicker
C# would be groovy, if it had that!
kenny
Who in the world is using Groovy?
Shiva
+3  A: 

So I just wanted to know how do you know when you can or can't do check for null?

You can check for null at any time you like (except with non-nullable value types, that cannot be null).

You should check for null at any time you wish to access the members of an object, and you are not certain that the variable containing the object is not null.

A couple of typical places for null check are:

  • You get an object passed to you as a parameters in a function you are writing. Do a null-check on the parameter before using it.
  • You call a method (or fetch a property value) returning an object that you wish to use. Do a null-check on that return value before using it.
  • You pass an object to a method where it is documented that it will throw a NullReferenceException if the parameter is null. Do a null check on the variable you wish to pass before calling the method.
Fredrik Mörk