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 

Also, this is not BP (trap-routing) - but it is the best isolation I can get.
But I get good waves telling me that "danger, danger - can be uninitialized." How is it going?

Edit:
Please do not suggest "Just put string foo = string.Empty; on" declaration "". I would like to announce this, but just complete the task on time!

+6
source share
6 answers

Some background from the C # specification (5.3.3.14):

To approve a try stt form:

try try-block finally finally-block

(...)

The specific state of assignment v at the beginning of the final block coincides with the specific state of assignment v at the beginning of STMT.

Edit Try-Catch-finally (5.3.3.15):

A specific assignment analysis for a try-catch-finally (...) statement is performed as if the statement was a try-finally expression containing a try-catch statement

The following example demonstrates how different attempt blocks (§8.10) affect a specific task.

 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 better shows the problem:

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

You will need to change the first line to string foo = null or initialize if necessary. As for the compiler, there may be an exception before foo is initialized in a try block, and the catch may also not occur.

+2
source

I think the problem is probably that there is a case where try and catch exceptions are thrown out. In this case, finally should be achieved, but with uninitialized foo . Since in this case the rest of the code will not be reached (the exception that was thrown in the catch takes us out of the method after finally ), this does not present a problem for the code after finally . This code can only be achieved by running try or catch blocks.

Since there is always the case that each individual assignment foo throws an exception, and since in this case the finally block will always work anyway, there is always the possibility of uninitializing foo .

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

+2
source

Declare your string foo at the class level to solve the problem.

EDIT: or

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

to try

 string foo = string.Empty; 
-2
source

Try the following:

 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 
-2
source

Source: https://habr.com/ru/post/916529/


All Articles