在try catch异常中的变量

3
在try代码块和catch代码块中使用变量有什么区别?
string curNamespace;

try
{
  curNamespace = "name"; // Works fine
}
catch (Exception e)
{
// Shows use of unassigned local variable  
throw new Exception("Error reading " + curNamespace, e);

}

如果我在try块中使用变量,它可以编译通过,在catch块中使用时会出现“使用未分配的变量”的错误提示。


“未分配变量的使用”是一个警告,如果您选择忽略它,那么问题就非常明显了。在尝试使用“curNamespace”之前,您没有为其分配值,因此请设置一个值。我实际上建议使用String.Empty而不是将其设置为null。 - Security Hound
6个回答

10
编译器报错是因为在值初始化之前可能会遇到异常。请考虑以下(非常牵强的)示例:
string curNamespace;
try {
    throw new Exception("whoops");

    curNamespace = "name"; // never reaches this line
}
catch (Exception e) {
    // now curNamespace hasn't been assigned!
    throw new Exception("Error reading " + curNamespace, e);

}

修复方法是在try..catch之外将curNamespace初始化为某个默认值。不过,我想知道你打算用它做什么。

他说:“它编译得很好”,所以并不像你说的那样是编译器在抱怨。 - Diego
1
@Diego 在你的环境中试试看。使用VS 2010和.NET 4,编译器肯定不允许默认情况下进行这样的操作。我想可以将其更改为警告 - 或者OP已经进行了更改。 - Yuck
@Yuck - 这个答案既“正确”又“不正确”。编译器报错的原因是变量在使用之前没有被赋值。但根据提供的代码,它已经被初始化(只是还没有被赋值)。 - Security Hound
@Yuck - 该代码可使用.NET 4进行编译,请调整您的警告设置,因为默认设置将允许此操作。 - Security Hound
1
@Diego,他说:“如果他在try部分使用它,它编译得很好。”但然后他继续报告编译器错误。根据推断,他已经尝试过不使用catch,现在又尝试了一下。正是catch的使用导致编译器出现问题。 - Anthony Pegram
1
根据我的了解,没有办法将编译器警告级别设置为忽略语言规范中非法的内容。我会怀疑您是否完全地编译了此代码。 - Anthony Pegram

3
这意味着在catch范围中使用变量curNamespace之前没有初始化它。
请将您的代码更改为以下内容:
string curNamespace = null;

而且它会编译通过。

C#中,变量必须在使用之前进行初始化。所以这是错误的:

string curNamespace; // variable was not initialized
throw new Exception("Error reading " + curNamespace); // can't use curNamespace because it's not initialized

1
那不是真的Pablo。curNamespace在try-catch块之外定义,因此它可以在try catch内部访问。 - Diego
1
不知道为什么这个被踩了,它是正确的。编译器无法确定变量在 catch 中使用之前是否已经被赋值。 - Anthony Pegram
1
@Diego,定义明确定义是两回事。Pablo的回答并没有涉及到定义。 - Anthony Pegram
1
@Diego:在回答之前没有完整阅读问题。现在已经进行了更正。谢谢! - Pablo Santa Cruz
1
我不知道为什么这个回答会被负评。这是正确的答案。没有必要进一步解释,因为这是C#标准的一部分。原始答案也是可以接受的。我不明白投诉的原因。 - Security Hound

3

你必须在try块之外分配它。

        string curNamespace = string.Empty; // or whatever

        try
        {
            curNamespace = "name";
        }
        catch (Exception e)
        {
            throw new Exception("Error reading " + curNamespace, e);
        }

0

如果你改变curNamespace的声明并给它赋值,它就会工作:

string curNamespace = null; /* ASSIGN SOMETHING HERE */
try
{
  curNamespace = "name";
}
catch (Exception e)
{
throw new Exception("Error reading " + curNamespace, e);

}

0

你必须先初始化curNamespace。否则,在catch分支中它可能未被初始化。


根据作者的示例代码,它不可能未被初始化(这显然发生了)。只是在使用之前从未赋值。这仅仅是一个警告,在示例代码的情况下可以忽略。 - Security Hound
@Ramhound,您似乎将“initialized”用于表示“defined”。这不是正确的用法。就此用法而言,初始化本质上是赋值。 - Anthony Pegram

0

由于变量在使用时不保证会保存任何值,因此您必须将某些值分配给该变量。

您可以使用以下代码:

string curNamespace = String.Empty;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接