【发布时间】:2015-06-20 14:07:27
【问题描述】:
我有一个小 C# 程序,它在 Debug 和 Release 版本之间产生不同的输出。我认为,发布版本的空输出与 C# 语言规范一致。这个程序不应该产生输出,但 Debug 版本会。
我已经从命令行(在 VS 环境之外)运行了 Release 和 Debug 版本,并获得了相同的不一致输出。我已经反编译了 Debug 版本(使用 ILDASM),然后使用 ILASM 重新编译了它。当我这样做时,新编译的程序的行为就像发布版本一样。我只能想象,当我反编译然后重新编译时,有些东西被遗漏了,但我无法确定有什么不同。
关于EXE文件大小:VS生产的Release和Debug版本文件大小相同:5120字节。当我反编译并重新编译时,两个版本再次具有相同但更小的文件大小:3,072。
程序很小,我查看了 Reflector 中的 IL,但看不到任何会导致输出差异的内容。
有没有人(希望是详细的)解释为什么会有差异?
请注意,我并不是试图使调试和发布版本保持一致,我想了解它们为什么不一致。
回想一下我上面所说的——调试和发布版本都会产生不同的输出即使是从命令行运行。如果您告诉我运行时正在为发布版本而不是为调试版本进行某种优化,那么必须在调试/发布版本程序集中嵌入一些东西,告诉运行时打开/关闭优化。那个嵌入的“东西”是什么?为什么在使用 ILDASM/ILASM 时它不能继承?
代码如下:
using System;
class Test {
static int value = 0;
static int a = Initialize("Assigning a");
static int b = Initialize("Assigning b");
static String name = "Fred";
static int c = Initialize("Assigning c");
static int Initialize(String mssg) {
++value;
Console.WriteLine("In Initialize() :: {0}, name={1}, returning {2}", mssg, name, value);
return value;
} // Initialize()
static void Main() {
} // Main()
} // class Test
这是 Visual Studio 生成的调试版本的输出:
In Initialize() :: Assigning a, name=, returning 1
In Initialize() :: Assigning b, name=, returning 2
In Initialize() :: Assigning c, name=Fred, returning 3
运行发布版本不会产生任何输出。
【问题讨论】:
-
最有可能的是,在发布模式下,未加载测试类,因为没有对它的引用。尝试将
Console.WriteLine(Test.name);添加到您的 main 方法中。 -
我建议放置一个
Console.WriteLine("In Main");以表明 main 实际上正在被调用。 (我刚试过你仍然得到不同的输出,但是如果你做更多,例如Console.WriteLine("In Main() :: {0}", name);,那么调试和发布开始表现相同) -
传呼飞碟先生,飞碟先生请到服务台
-
如果你愿意,我发现this MSDN blog 展示了如何禁用调试优化,这样你仍然可以在调试器中看到不同的行为(如果你选中“启用地址级调试”框,你可以从 Disassemby 窗口看到汇编代码)。我知道发生了什么(JITed 代码不调用其他静态方法),但我不知道 为什么 它正在发生,所以我不打算发布回答只是猜测。
标签: c# debugging release language-lawyer