我是否需要初始化变量,即使我知道它将在使用之前分配?

时间:2011-10-28 07:09:33

标签: c# asp.net-mvc

在ASP.NET MVC应用程序中,我的代码可归结为以下内容:

public ActionResult Test() {
    string query;
    try {
        query = GenerateQueryString();
    }
    catch (Exception ex) {
        ModelState.AddModelError("error", ex.Message);
    }

    ... do additional validation ...

    if (ModelState.IsValid) {
        return RedirectToAction("Success?" + query);
    }

    return View(); // Show validation messages
}

上面的代码有编译错误...... query可能未初始化。

但是,代码中的逻辑在使用之前会清楚地初始化query

解决此问题的最佳方法是什么?

9 个答案:

答案 0 :(得分:2)

C#编译器正在查看您的代码并看到变量的值在try块中初始化,然后在以后使用。它可以看到执行的逻辑分支存在于抛出异常,捕获异常,然后使用未初始化的值执行后续代码。

扼杀错误的最简单方法是为字段分配默认值。 null就足够了。当您将错误添加到MVC模型状态并在访问query之前检查该值时,您应该处于默认值无关紧要的情况。

答案 1 :(得分:1)

你错了,如果GenerateQueryString抛出异常怎么办?查询的价值是什么?

您可能想要查询=“错误”;或者你的捕获块里的东西。这是因为如果抛出GenerateQueryString中的异常,您显然希望应用程序运行。

修改

我建议不要使用默认值预设查询。这是因为意义不同。默认值不同于某个时刻的某个值。这样做还会阻止编译器在您创建新代码路径时向您发出警告,但忘记为查询设置值

答案 2 :(得分:1)

如果对GenerateQueryString的调用存在异常,则query的值将不确定。

尝试

string query = string.Empty;

对变量进行明确赋值。
或者,如果异常应该中止执行,这也将起作用:

string query;
try {
    query = GenerateQueryString();
}
catch (Exception ex) {
    ModelState.AddModelError("error", ex.Message);
    return View();
}

答案 3 :(得分:1)

守则未明确初始化。当GenerateQueryString()方法抛出异常时,不会设置任何值。您应该将String设置为null并在使用之前检查null,并且您不会在catch块中断。

答案 4 :(得分:1)

仅仅因为你知道它会被初始化(它可能不在你的代码中),编译器无法知道 - 它被称为Halting problem

所以编译器在谨慎方面犯了错误,.net做了很多事情(例如,在switch..case中没有任何漏洞)。

答案 5 :(得分:1)

这里的事情是必须在读取之前初始化局部变量 - 默认情况下它们不会被初始化,这可以防止程序员经常犯的错误。前段时间我一直在寻找这种简单情况的答案:

bool a = true, b;
if (a == true) //here everything is OK, because a is initialized
   b = true;
if(b == false) //here you get an error, I thought b == false by default
   return;

我在stackoverflow上找到了深刻的解释,为什么它如此工作(在我正在阅读的那一刻找不到)。但是你可以阅读Absence of evidence is not evidence of absence有趣的文章。也许它会解释我试图说的:)

<强>恢复

在您的情况下,您需要初始化query或在catch块中设置变量

答案 6 :(得分:0)

只需更改string query = string.Empty;中的查询声明。

答案 7 :(得分:0)

问题是查询是在try块中初始化的,但查询是在上面的块中声明的。您必须在顶级块初始化它。

答案 8 :(得分:0)

可能只是你的GenerateQueryString()抛出异常。就个人而言,我更喜欢初始化我的变量,只是为了安全起见。出于这个原因,您可能只是初始化以查询:

string query = String.Empty;

安全方面没有坏处。