我不明白为什么以下代码会产生错误。通常我可以从语言规范中找出问题,但在这种情况下我不理解语言规范。
这不会导致我的代码出现问题,顺便说一下,我只想了解这种语言。
示例:
bool success;
try
{
success = true;
}
catch
{
success = false;
}
finally
{
Console.WriteLine(success); // ERROR: Local variable 'success' might not be initialized before accessing
}
此行为似乎适用于所有版本的C#,但以下引用来自C# Language Specification 5.0。
第5.3.3.14节试用终止语句
最后一个块开头的v的明确赋值状态与stmt开头的v的明确赋值状态相同。
这里“stmt的开头”是指整个try-finally语句的开头,即try
之前。
第5.3.3.15节 Try-catch-finally语句
以下示例演示了try语句的不同块(第8.10节)如何影响明确赋值。
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
}
有人可以解释为什么success
(在我的例子中)或i
(在语言规范示例中)在finally块的开头没有明确分配?
答案 0 :(得分:5)
原因很简单 - 在try
阻止之前,无法保证catch
或finally
块中的代码能够执行。
ThreadAbort
异常可能发生在try
块内,但在分配执行之前。
运行时代码在抛出异常之后但在catch
块中的代码执行之前执行(搜索异常处理如何在.Net或"结构化异常处理")。
因此,在执行finally
块之前,try和catch块中的代码可能永远不会执行。
答案 1 :(得分:2)
正如Vikas所说,异常也可能在catch块内发生,将控制传递给finally,而不运行整个catch块。无法保证任何一项任务实际完成。
为什么要设计语言以便更容易编写错误的代码?好的代码只能捕获特定的异常,或者捕获并记录所有异常,然后重新抛出它无法识别的异常。只有遇到并忽略所有异常的错误代码才会遇到这种情况。
此外,修复非常容易。