4

In the following code, if cmd has been initialized, then I'll make to sure to close any open connections before throwing an exception. However, even after I check that cmd is not null, I still get a possible null reference warning in subsequent lines of code.

Dim cmd As SqlCommand
Try
    'Do some Stuff
Catch ex As Exception
    If cmd IsNot Nothing AndAlso
       cmd.Connection IsNot Nothing AndAlso              '<- null cmd warning 
       cmd.Connection.State = ConnectionState.Open Then  '<- null cmd warning 
        cmd.Connection.Close()                           '<- null cmd warning 
    End If
    Throw
End Try

I get the two following warnings (possibly one from Resharper & one from Visual Studio):

  • Variable 'x' might not be initialized before accessing. A null reference exception could occur at runtime.
  • BC42104: Variable 'x' is used before it has been assigned a value. A null reference exception could result at runtime.

According to the Visual Studio Page:

An application has at least one possible path through its code that reads a variable before any value is assigned to it.

But I don't think there is even one possible path through the code where the variable would be used without being initialized.

  • Have I made some error or is this a bug?
  • Is there a way to disable this warning from coming up?

Here's a screenshot:

screenshot

This is different from many similar questions already asked here, like Prevent Resharper “Possible Null Reference Exception” warnings because I'm not trying to allow for a NullableType, but instead have already guaranteed that my variable is not null.


Update:

Follow up question: Why?

Whether my object is never initialized or initialized to Nothing, in both cases cmd IsNot Nothing should resolve to False, so anything after the AndAlso should never be executed.

Dim cmd1 As SqlCommand
Console.Write(cmd1 IsNot Nothing) 'False

Dim cmd2 As SqlCommand = Nothing
Console.Write(cmd2 IsNot Nothing) 'False

Maybe the compiler just doesn't have a good way of guaranteeing this at compile time.

Community
  • 1
  • 1
KyleMit
  • 30,350
  • 66
  • 462
  • 664

2 Answers2

4

Your problem is not that your value is null, the problem is that your object is not initialized at all. For example:

    static void Main(string[] args)
    {
        List<int> empty;

        if (empty != null)
        {
            Console.WriteLine("no");
        }
    }

Will not compile, because empty has no value. If I change the code to:

    static void Main(string[] args)
    {
        List<int> empty = null;

        if (empty != null)
        {
            Console.WriteLine("no");
        }
    }

It'll work, because my list now has a value, it's null, but it still exists.

EDIT: Sorry I used C# instead of VB, that's because that editor I have handy, but the code is correct. You initialize your variables every time and you'll not gonna get the error.

Fedor Hajdu
  • 4,657
  • 3
  • 32
  • 50
  • I don't see a downvote and I definitely didn't downvote you. Perhaps someone upvoted and then retracted? If you click on the score it will give you the breakdown of upvotes vs. downvotes. – KyleMit Feb 26 '14 at 15:43
  • Am sorry it is my downvote. and it's my upvote too :) Reason I downvoted because I know this won't compile in c# but strange that vb.net compiler just gives a warning. It compiles fine. I was under the impression that this won't compile in vb.net too intuitively; but then op says he gets a warning. good to know new thing. btw good answer :) – Sriram Sakthivel Feb 26 '14 at 15:49
3

If you put

Dim cmd As SqlCommand = Nothing

It should be ok..

trucker_jim
  • 572
  • 3
  • 7
  • 1
    I guess my follow up question is why? Whether my object is not initialized or initialized to nothing, in both cases `cmd IsNot Nothing` should resolve to `False`, so anything after the `AndAlso` should never be executed. – KyleMit Feb 26 '14 at 15:50
  • I'm sure it's just generic behavior. If you took a date variable for example, that would not be nothing. Try running this: Dim dt As Date : If IsNothing(dt) Then Throw New Exception("Hello"). It's just trying to encourage you to always put a value into a variable, even if it's nothing because some variables if not initialised will not resolve to nothing :) – trucker_jim Feb 26 '14 at 15:53