在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警告。
答案 0 :(得分:21)
事实证明,当赋值操作的右侧不是编译时常量时,会禁止此警告。
微软Visual Studio反馈网站上发布的已删除文章解释说,这是因为他们有很多投诉来自纯粹分配变量的人,因此他们可以看到调试期间返回的方法调用,并发现警告令人恼火:
在这种情况下,抑制“已分配但从未使用过”的警告 受到执行此操作的用户反馈的推动:
“嘿,”用户在调试时说,“我不知道BlahBlah是什么 回来?“但是没有简单的方法可以检查回报值 调试器,因此用户经常这样做:int Blah(){ // blah BlahBlah(x, y, z) // blah // blah }
int Blah() { // blah int temp = BlahBlah(x, y, z) // blah // blah }
然后使用locals或watch窗口来检查temp。温度是 从未在功能中的任何其他地方使用过,因此产生了刺激性 “已分配但未阅读”警告。
我认为这有点遗憾:
无论如何,我知道你不能取悦所有人。
答案 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会考虑不使用该案例。