Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么没有对这个未使用的变量给出警告?_C#_Visual Studio_Warnings_Monodevelop - Fatal编程技术网

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

C# 为什么没有对这个未使用的变量给出警告?,c#,visual-studio,warnings,monodevelop,C#,Visual Studio,Warnings,Monodevelop,在VS2010、VS2008或Windows上的MonoDevelop中编译以下程序时,我收到警告:“变量'y'已赋值,但从未使用过它的值” 为什么在VisualStudio中编译时对x没有警告 有趣的是,在Mac OS x上用MonoDevelop进行编译时,我确实收到了关于x和y的CS0219警告。我可能会离开这里,但我认为这是因为y只被设置了,而x被实例化成了一些非常重要的东西-实例化可能会在New()方法中涉及单独的操作,由于实例化变量可能会产生副作用,因此不认为未使用。在您的例子中,它

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

为什么在VisualStudio中编译时对
x
没有警告


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

我可能会离开这里,但我认为这是因为y只被设置了,而x被实例化成了一些非常重要的东西-实例化可能会在New()方法中涉及单独的操作,由于实例化变量可能会产生副作用,因此不认为未使用。在您的例子中,它只是一个base object(),因此没有影响,但可能编译器不够聪明,无法区分两者之间的区别


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

我的直觉是,作为
x
引用类型,编译器不会显示任何警告,因为构造函数可能正在执行某些可能非常“有意义”的操作;相比之下,
y
是一种值类型,其值仅分配给,但从未使用,编译器很容易告诉你,如果你不打算引用它,就没有任何意义。

日食会考虑未使用的情况。

RESARPER也会警告你X未被使用。

可以是因为<代码> x/COD>是引用类型,因此被存储在堆中,它将阻止该对象的垃圾收集,直到

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

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

Microsoft Visual Studio反馈网站上的一篇自删除帖子解释说,这是因为他们收到了很多人的投诉,这些人纯粹是为了查看调试过程中方法调用返回的结果而分配变量,并发现警告令人恼火:

在这种情况下,“已分配但从未使用”警告的抑制 这是出于用户的反馈:

int Blah(){
    // blah
    BlahBlah(x, y, z)
    // blah
    // blah
}
“嘿,”用户在调试时说,“我想知道BlahBlah是什么 返回?”但没有简单的方法检查 调试器,因此用户经常执行以下操作:

int Blah()
{
    // blah
    int temp = BlahBlah(x, y, z)
    // blah
    // blah
}
然后使用局部变量或观察窗口检查温度。临时工 在函数中从未在其他任何地方使用过,因此它产生了一种恼人的效果 “已分配但未读取”警告

我觉得这有点遗憾,因为:

  • 事实上,我发现这些警告在MonoDevelop中给出时很有用
  • 任何人都可以自己抑制警告(不可否认,他们也会抑制未使用的编译时常量赋值的警告-也许应该有一个单独的警告?)

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

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

    这很有意义,但是你可能认为编译器应该知道像
    object
    这样的系统对象不会有副作用。@StevenBurnap编译器在处理像这样的“明显”信息时不是很聪明。通常这是因为添加逻辑来跟踪这些事情(小)的好处并不超过编译器增加的复杂性(大)的成本。我不相信这个答案。因此,可以保留运行编译器的效果:
    void Main(string[]args){new object();int y=0;}
    @StevenBurnap创建新的
    对象
    确实有副作用:它分配内存。如果没有别的,它会产生内存压力——这很可能是您的意图。当有副作用时,编译器不可能“知道”有“没有副作用”。我之前的评论应该是“…运行构造函数的效果…”,而不是“编译器”!但是您可以保留
    new object()
    调用,而不将结果分配给variable.AFAIK,该变量仅在调试器中运行时适用,在这种情况下,运行时会将局部变量的活动范围扩展到整个方法。在发布模式下,它们可以短得多——或者在本例中完全消除。现在你可以了,还有理由禁用此警告吗?有没有办法重新打开此警告?我来这里询问是否有人知道如何重新打开此警告…这是因为开发人员正在启动大量的变量,而没有使用它们(重,我的意思是实例化一个在不必要的时候做很多事情的类)“无论如何,我理解你不能取悦所有人。”这不像是用户可以设置的选项。”\_(ツ)_/'@Ergwun这不是针对您的,抱歉。这是一个玩笑,微软可以添加一个选项,如果它应该生成警告。Eclipse是一个java IDE。这个问题是关于C#的。
    int Blah()
    {
        // blah
        int temp = BlahBlah(x, y, z)
        // blah
        // blah
    }