In C#, why is a variable not definitely assigned at the beginning of a finally block?

旧街凉风 提交于 2021-02-20 16:58:52

问题


I don't understand why the following code produces an error. Normally I can figure things out from the language specification, but in this case I don't understand the language specification.

This isn't causing problems in my code, by the way, I just want to understand the language.

Example:

bool success;
try
{
    success = true;
}
catch
{
    success = false;
}
finally
{
    Console.WriteLine(success); // ERROR: Local variable 'success' might not be initialized before accessing
}

This behavior appears to be true of all versions of C#, but the quotes below are from C# Language Specification 5.0.

Section 5.3.3.14 Try-finally statements

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.

Here "beginning of stmt" refers to the beginning of the entire try-finally statement, i.e. just before try.

Section 5.3.3.15 Try-catch-finally statements

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

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
}

Can anyone explain why success (in my example) or i (in the language spec example) are not definitely assigned at the beginning of the finally-block?


回答1:


Simple reason is - There is no guarantee that the code in try or catch block will ever execute, before finally block.

ThreadAbort Exception can happen inside the try block, but before assignment executes.

Runtime code executes after exception is thrown but before code in catch blocks executes (Search for how exception handling works in .Net or "Structured Exception Handling").

Hence, code in try and catch block may never execute, before execution of finally block.




回答2:


  1. As Vikas said, exceptions can happen inside catch block too, passing control to the finally without running the whole catch block. There's no guarantee that either of the assignments actually completed.

  2. Why design the language to make it easier to write bad code? Good code will catch only specific exceptions, or catch and log all but then rethrow the ones it doesn't recognize. Only bad code that catches and ignores all exceptions can even run into this case.

Besides, the fix is incredibly easy.



来源:https://stackoverflow.com/questions/28755949/in-c-why-is-a-variable-not-definitely-assigned-at-the-beginning-of-a-finally-b

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!