为什么没有给这个未使用的变量发出警告?

时间:2012-05-15 02:46:56

标签: c# visual-studio warnings monodevelop

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

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

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

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

7 个答案:

答案 0 :(得分:21)

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

微软Visual Studio反馈网站上发布的已删除文章解释说,这是因为他们有很多投诉来自纯粹分配变量的人,因此他们可以看到调试期间返回的方法调用,并发现警告令人恼火:

  

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

int Blah(){
    // blah
    BlahBlah(x, y, z)
    // blah
    // blah
}
     “嘿,”用户在调试时说,“我不知道BlahBlah是什么   回来?“但是没有简单的方法可以检查回报值   调试器,因此用户经常这样做:

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

然后使用locals或watch窗口来检查temp。温度是   从未在功能中的任何其他地方使用过,因此产生了刺激性   “已分配但未阅读”警告。

我认为这有点遗憾:

  1. 我实际上发现这些警告在MonoDevelop中给出时很有帮助。
  2. 任何人都可以自己压制警告(诚然,他们也会压制未使用的编译时常量分配 - 可能应该有一个单独的警告吗?)。
  3. 无论如何,我知道你不能取悦所有人。

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

我的预感是,作为x引用类型,编译器不会显示任何警告,因为构造函数可能正在执行某些可能非常“有意义”的操作;相比之下,y是一个值类型,其值只被赋值但从未使用过,编译器很容易告诉你,如果你不打算在线上引用它就没有意义。< / p>

答案 3 :(得分:1)

Resharper还会警告你x未被使用。

答案 4 :(得分: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
    }
}

答案 5 :(得分:0)

y在堆栈上,x在堆上(提示:x使用new关键字)。因此,某些调试器/编译器警告可能会考虑像x这样的堆/全局变量让程序员担心,因为低级代码或调试探针可能正在幕后使用它们。但是像y这样的堆栈变量完全在编译器的控制之下,并且可以轻松地证明可检测未使用的冗余变量。

答案 6 :(得分:-1)

Eclipse会考虑不使用该案例。