tags:

views:

22

answers:

1

I recently wrote a section of code wherein upon finishing, I received a warning from the compiler telling me that one of my variables is being used before it is assigned a value. In practice, the method call on this object will never be made without the object being instantiated beforehand. Here is the snippet of code

Try
    fs = New FileStream(fileName, FileMode.Open)
    Dim PolarMatrix As PolarMatrix
    PolarMatrix = DirectCast(bf.Deserialize(fs), PolarMatrix)
    fs.Close()
    Return TypeOfStructure.Polar
Catch ex As Exception
    fs.Close() 'Warning on this line: Variable 'fs' is used before it has been assinged a value
End Try

I assume I'm receiving this warning because the first line in the Try section may be the line to throw the error, and the Object will never be instantiated. FileName though, is a variable being passed to this method which has already been checked for errors, so it is guaranteed to be correct. The error I'm expecting to perhaps be thrown comes during the deserialization.

So my question: When warnings are given on objects that the compiler thinks may not have been instantiated, does this overrule the user knowing that a problem will never arise on that line? Is it sometimes necessary to add code simply to appease the compiler? Or is what I've done here bad practice?

+2  A: 

How are you sure that fs will always be instantiated, even if the filename is correct, it could still fail to open for many other reasons.

However, the easy solution to this problem would be to get rid of the catch completely and use a Using statement instead, as:

Try
    Using fs = New FileStream(fileName, FileMode.Open)
        Dim PolarMatrix As PolarMatrix
        PolarMatrix = DirectCast(bf.Deserialize(fs), PolarMatrix)
        Return TypeOfStructure.Polar
    End Using
 Catch ex as Exception
      ' do something here
 End Try

This means that the fs will be automatically disposed of when this section of code exists, and Stream.Dispose closes the stream.

And to answer your actual question, sometimes the compiler is wrong, and you will have to either ignore the warnings or add some extra code to make them go away, but in general, assume that the compiler is correct until you're absolutely sure that that's not the case.

ho1
I don't quite understand how this section of code is a viable alternative to what I currently have. How is this method checking for exceptions? The point of my original try-catch was to take care of exceptions during the deserialization. With this code, I just get the error again. The reason the return statement immediately follows is that if the deserialization is successful, I know that the structure type is Polar. Otherwise, I perform other checks.
AndyPerfect
@AndyPerfect: Since the `Catch` only closed the connection which is already done by the `Using` statement I didn't think it was useful any longer, but if you want to catch other errors, then use the code as in my updated answer. Be aware though, just catching exceptions without doing anything with them is usually not a good idea since it's easy to introduce hard to find bugs, at the very least it would probably be worth to log all errors in some way.
ho1
Very nice! I didn't realize the Using statement disposed of the object in question at the "End Using" statement.
AndyPerfect