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

问题描述 投票:0回答:8

在 Windows 上的 VS2010、VS2008 或 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 警告。

c# visual-studio warnings monodevelop
8个回答
27
投票

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

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

在这种情况下抑制“已分配但从未使用”警告 受到这样做的用户反馈的激励:

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

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

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

然后使用本地或监视窗口检查温度。温度是 从未在该函数的其他任何地方使用过,因此它产生了令人恼火的结果 “已分配但未读取”警告。

我认为这有点遗憾:

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

无论如何,我明白你无法取悦所有人。


2
投票

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

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


2
投票

我的预感是,作为

x
一个引用类型,编译器不会显示任何警告,因为构造函数可能正在执行一些很可能“有意义”的操作;相反,
y
是一种值类型,其值仅被分配但从未使用,编译器很容易告诉您,如果您不打算直接引用它,则这样做没有意义。


1
投票

ReSharper 还会警告您 x 未使用。


0
投票

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


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
    }
}

0
投票

在 .NET 5 之前,您可以通过 FxCopAnalyzers NuGet 包(如 CA1804)捕获此错误,但在过渡到 roslyn-analyzers 期间不知何故中断了。

我发现正确捕获此错误的唯一方法(截至撰写本文时)是使用支持它的

StyleChecker NuGet 包

https://github.com/maroontress/StyleChecker/blob/main/doc/rules/UnusedVariable.md


-1
投票
Eclipse 将认为该案例未使用。

© www.soinside.com 2019 - 2024. All rights reserved.