views:

98

answers:

2

Why can't I assign object variables within the try block?

If I attempt to do this and clean up the variable in the finally block I get a compiler error: "use of unassigned local variable". This makes no sense because the variable is declared before the try block, and in the finally block I am first checking whether the variable is null.

Why can't the following code compile? I am checking whether dbc is null so there's no chance of it trying to do something with an unassigned variable.

eg:

DbConnection dbc;
try {
    dbc = <some method call returning an open DbConnection>
    // do stuff
} catch (Exception e) { // do stuff }
finally { 
    if (dbc != null) {
        dbc.Close();
    }
}
+11  A: 

Change your declaration to DbConnection dbc = null; so the compiler can know for certain that the variable is assigned. (Merely declaring dbc is not the same as assigning it a value of null, you must be explicit with a local.)

The reason your existing code fails is that it is entirely possible for an exception to occur before dbc is set. As such, the compiler cannot assume that dbc is assigned by the time the finally block executes.

For more info, see section 5.3 of the language specification on definite assignment.

http://msdn.microsoft.com/en-us/library/aa691172(VS.71).aspx

Anthony Pegram
Surely the variable is null if it is not assigned?
Craig Johnston
@Craig, no, the variable is merely unassigned. `null` does not constitute the lack of assignment.
Anthony Pegram
Is this peculiar to C#? I don't remember this in any other language.
Craig Johnston
Global and member variables get auto-nulled, I believe. Local variables do not ... for efficiency purposes. Don't quote me on this one, look it up.
Hamish Grubijan
@Craig: Javascript behaves the same way: `null` and `undefined` [mean two slightly different things](http://joeyjavas.com/2007/04/25/javascript-difference-between-null-and-undefined/).
josh3736
Just like VB.NET, C# also automatically nulls local variables. However, unlike VB.NET, the C# compiler thinks you probably made a mistake by having a path through your code that never initializes it. That catches a *lot* of bugs.
Hans Passant
A: 

Change this

DbConnection dbc;

to this

DbConnection dbc = null;
jwsample