【问题标题】:Compiler error - "use of unassigned local variable". what can go wrong?编译器错误 - “使用未分配的局部变量”。会出什么问题?
【发布时间】:2018-01-20 18:49:11
【问题描述】:

我读过的几乎每一篇博客都说编译器标记错误“使用未分配的局部变量”说明了它的设计决定,因为历史表明未分配的变量是错误的来源,编译器希望阻止你这样做。

我不确定分配给局部变量如何帮助我不注入错误甚至减少引入错误的机会。

我可以分配一个局部变量作为某个方法的返回值,该方法可能有错误并最终导致错误的分配。所以我不认为编译器在这个意义上对我有帮助。如果设计人员决定考虑未分配的局部变量的默认值,开发人员会处理它并且在“可能引入错误”的情况下会是相同的,不是吗?

谢谢!!

【问题讨论】:

  • 这个问题太笼统了。对于大多数人来说,很明显为什么GIGO 适用并且应该避免使用。对于那些不明显的人来说,堆栈溢出的答案要引导某人解决问题需要比合理的空间更多的空间。
  • 未赋值的变量可能意味着其定义中的拼写错误。如果代码中使用了未定义变量但拼写正确,则错误将是“未定义变量”。但是程序员会认为他们已经定义了它。他们没有,因为他们在定义中拼错了它。添加未分配变量警告将突出显示拼写错误的行。

标签: c# language-design local-variables


【解决方案1】:

使用未分配的变量可能是潜在的错误,也可能不是(几乎总是如此)。这里的问题是;如果它一个错误,你想什么时候知道它?在编译时或运行时,如果代码足够复杂或引入的错误很微妙,则相对难以发现?

一个简单的例子:

string Join(params object[] array)
{
    string foo;

    foreach (var o in arr)
        foo += o.ToString();
}

所以现在,我们有两个选择:编译器让您愉快地编译它并观察您在运行时崩溃和烧毁,或者它直接告诉您有错误。后一种选择对我来说似乎更好。

现在,当您写这个问题时,您可能更多地考虑值类型而不是引用类型;未分配的引用类型实际上是直接的NullReferenceException,虽然很麻烦,但在您第一次运行代码时很容易修复。

相反,值类型具有 可用 默认值,但这会使情况变得更糟。现在,也许您忘记将变量初始化为合理的值,并且在运行时没有明显的问题,但也许您刚刚在程序中引入了一个不太明显的错误:

int totalDays(DateTime date)
{
    DateTime now; //TODO: initialize to server time, not local DateTime.Now
    return (now - date).TotalDays;
}

编写此代码时,您的咖啡洒了,然后您的妻子打来电话,告诉您您的狗生病了,吐在您最喜欢的(且昂贵的)地毯上,并在您开着全新的汽车去兽医的路上。 .. 当你回来的时候,你已经忘记了totalDays(我写完了不是吗?)你开始在你的项目中处理其他的东西。在一天/一周结束时,您需要在截止日期前提交代码中的错误。编译器可以轻松地警告您正在发生有异味的事情。为什么你不想要它?

相信了吗?

【讨论】:

  • 深信不疑,因为当您忘记将变量分配给某个值时它会有所帮助 - 但当您忘记分配默认值时则不会。所以是的,对于“然后你接到一个电话......”这样的情况。
  • 开发者显式将局部变量赋值为默认值或忘记自行赋值时程序执行的结果是相同的。甚至发生这种情况的可能性本身就令人担忧。
  • @RahulAgarwal 结果不一样:一个是错误,编译器会告诉你另一个不是。这就是该功能的重点。如果您将变量显式设置为其默认值,那么编译器将理解您知道您在做什么,就像处理其他合法代码一样;如果它编译然后炸毁一个核反应堆,因为它有一个错误,那就是你的问题。编译器尽可能地帮助你,但确保你的代码没有错误并不是它的工作。
  • 我同意。实际上 - 我应该在我的评论中更明确地说 - “编译器负责避免这种令人担忧的情况”:)
【解决方案2】:

假设您有一个变量用于与另一个变量相乘,如果在乘法发生时该变量没有赋值,则会出现错误。这就是编译器想要避免的,因为编译器不知道以后是否会初始化变量。

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    相关资源
    最近更新 更多