user57508
user57508

Reputation:

Why is my variable still "uninitialized"?

string foo;
try
{
    foo = "test"; // yeah, i know ...
}
catch // yeah, i know this one too :)
{
    foo = null;
}
finally
{
    Console.WriteLine(foo); // argh ... @#!
}
Console.WriteLine(foo); // but nothing to complain about here

Besides it's not BP (catching-routing) - but this is the best isolation I can get.
But I get nice waves telling me "danger, danger - might be uninitialized". How comes?

Edit:
Please do not suggest "Simply put a string foo = string.Empty; at the 'declaration'". I'd like to declare it, but just do the assignment on time!

Upvotes: 6

Views: 449

Answers (6)

Ral Zarek
Ral Zarek

Reputation: 1076

Some background from the C# specification (5.3.3.14):

For a try statement stmt of the form:

try try-block finally finally-block

(...)

The definite assignment state of v at the beginning of finally-block is the same as the definite assignment state of v at the beginning of stmt.

Edit Try-Catch-Finally(5.3.3.15):

Definite assignment analysis for a try-catch-finally statement (...) is done as if the statement were a try-finally statement enclosing a try-catch statement

The following example demonstrates how the different blocks of a try statement (§8.10) affect definite assignment.

class A
{
  static void F() 
  {
    int i, j;
    try {
      goto LABEL;
      // neither i nor j definitely assigned
      i = 1;
      // i definitely assigned
    }
    catch {
      // neither i nor j definitely assigned
      i = 3;
      // i definitely assigned
    }
    finally {
      // neither i nor j definitely assigned
      j = 5;
      // j definitely assigned
    }
    // i and j definitely assigned
    LABEL:;
    // j definitely assigned
  }
}

I just thought of an example that shows the problem better:

int i;
try
{
    i = int.Parse("a");
}
catch
{
    i = int.Parse("b");
}
finally
{
   Console.Write(i);
}

Upvotes: 3

Darshana
Darshana

Reputation: 2548

Declare your string foo at class level it will solve the problem

EDIT : or

string foo = "default";
try
{
    foo = "test"; 
}
catch (Exception) 
{
    foo = null;
}
finally
{
    Console.WriteLine(foo); 
}

Upvotes: 0

Dave Cousineau
Dave Cousineau

Reputation: 13148

I think the problem probably is that there is the case where both the try and catch throw exceptions. In that case, the finally should still be reached, but with an uninitialized foo. Since in that case, the rest of the code will not be reached (the exception that was thrown in the catch block takes us out of the method after the finally), this does not present a problem for the code after the finally. That code can only be reached if either the try or catch blocks ran.

Since there is always the case that every single assignment to foo threw an exception, and since in that case the finally block will always run anyway, there is always the possibility of foo being uninitialized.

As far as I can tell, the only way around this is to provide an initialization value for foo.

Upvotes: 2

Erik-RW
Erik-RW

Reputation: 173

Try this one:

string foo = null;
try
{
    foo = "test"; // yeah, i know ...
}
catch // yeah, i know this one too :)
{
}
finally
{
    Console.WriteLine(foo); // argh ... @#!
}
Console.WriteLine(foo); // but nothing to complain about here

Upvotes: -2

manojlds
manojlds

Reputation: 301037

You will have to change the first line to string foo = null or initialize as needed. As far as the compiler is concerned, there might be an exception before the foo is intialized in try block and the catch may not happen as well.

Upvotes: 2

Paul
Paul

Reputation: 3142

try

string foo = string.Empty;

Upvotes: -2

Related Questions