19

在 Windows 上的 VS2010、VS2008 或 MonoDevelop 中编译以下程序时,我收到警告CS0219,“变量 'y' 已分配,但它的值从未使用过”。

namespace Problem
{
    public class Program
    {        
        private static void Main(string[] args)
        {
            object x = new object();
            int y = 0;
        }
    }
}

x为什么在 Visual Studio 中编译时没有警告?

有趣的是,在 Mac OS X 上的 MonoDevelop 中编译时x 我确实收到了 CS0219 警告。y

4

7 回答 7

26

事实证明,当赋值操作的右侧不是编译时常量时,会抑制此警告。

微软的 Visual Studio 反馈网站上一篇已被删除的帖子解释说,这是因为他们收到了很多来自纯粹分配变量的人的抱怨,以便他们可以看到在调试期间返回的方法调用,并发现警告令人恼火:

在这种情况下,抑制“已分配但从未使用”警告的动机是来自执行此操作的用户的反馈:

int Blah(){
    // blah
    BlahBlah(x, y, z)
    // blah
    // blah
}

“嘿,”用户在调试时说,“我想知道 BlahBlah 返回的是什么?” 但是在调试器中检查返回值并没有简单的方法,所以用户经常这样做:

int Blah()
{
    // blah
    int temp = BlahBlah(x, y, z)
    // blah
    // blah
}

然后使用当地人或观察窗口检查温度。temp 从未在函数的其他任何地方使用过,因此它产生了一个恼人的“已分配但未读取”警告。

我认为这有点遗憾,因为:

  1. 我实际上发现这些警告在 MonoDevelop 中给出时很有帮助。
  2. 任何人都可以自己压制警告(诚然,他们也会压制未使用的编译时常量分配的警告——也许应该有一个单独的警告?)。

无论如何,我明白你不可能取悦所有人。

于 2012-05-17T02:10:40.323 回答
2

我可以离开这里,但我认为这是因为 y 仅设置,而 x 被实例化为非平凡的东西 - 实例化可能涉及 New() 方法中的单独操作,并且由于实例化变量可能会产生副作用,它不被认为是未使用的。在您的情况下,它只是一个基本对象(),所以没有影响,但也许编译器不够聪明,无法区分。

另一方面,使用 y 时,实例化没有副作用,因此它被视为未使用 - 如果完全删除,应用程序的代码路径将保持不变。

于 2012-05-15T02:52:37.400 回答
2

我的预感是,作为x引用类型,编译器不会显示任何警告,因为构造函数可能正在执行一些可能非常“有意义”的操作;相反,y作为一个值类型,它的值只被分配但从不使用,编译器很容易告诉你,如果你不打算引用它,那么这样做是没有意义的。

于 2012-05-15T02:52:57.767 回答
1

ReSharper 还会警告您 x 未使用。

于 2012-05-15T04:12:55.103 回答
0

可能是因为它x是一个引用类型,因此存储在堆上,它会阻止该对象的垃圾收集,直到x超出范围。

例如:

void main(string[] args)
{
    object x = new object();
    while (true)
    {
        // Some threading stuff
        // x is never garbage collected
    }
}

对比:

void main(string[] args)
{
    new object();
    while (true)
    {
        // Some threading stuff
        // The unreferenced object IS garbage collected
    }
}
于 2012-05-15T04:38:01.900 回答
0

y 在堆栈上,x 在堆上(提示:x 使用 new 关键字)。因此,一些调试器/编译器警告可能会考虑将诸如 x 之类的堆/全局变量留给程序员来担心,因为低级代码或调试探针可能在幕后使用它们。但是像 y 这样的堆栈变量完全在编译器的控制之下,并且能够很容易地检测到未使用的冗余变量。

于 2019-07-27T14:38:08.807 回答
-1

Eclipse 将考虑未使用的情况。

于 2012-05-15T02:55:13.430 回答