.NET编译器-调试与发布

时间:2020-03-05 18:43:30  来源:igfitidea点击:

多年来,我一直在VB.NET中使用DEBUG编译器常量将消息写入控制台。我也一直在以类似的方式使用System.Diagnostics.Debug.Write。据我所知,当将RELEASE用作构建选项时,所有这些语句都被编译器遗漏,从而使生产代码免除了调试语句的开销。最近,当使用Silverlight 2 Beta 2时,我注意到Visual Studio实际上添加到了我在一个公共网站上运行的RELEASE构建中,并显示了我认为甚至没有编译过的DEBUG语句!现在,我的第一个倾向是假设我的环境有问题,但是我还想问一个对System.Diagnostics.Debug和DEBUG build选项有深入了解的人,总体上我可能在这里误解了什么。

解决方案

回答

以我的经验,在VB.NET中的"调试"和"发布"之间进行选择没有什么区别。我们可以将自定义操作添加到这两种配置中,但是默认情况下,我认为它们是相同的。

使用Release肯定不会删除System.Diagnostics.Debug.Write语句。

回答

我要做的是将对Debug的调用封装在我自己的类中,并添加一个precompiler指令

public void Debug(string s)
{
#if DEBUG
    System.Diagnostics.Debug(...);
#endif
}

回答

就像我们说的那样,使用DEBUG编译器符号实际上将省略程序集中的代码。

我相信System.Diagnostics.Debug.Write将始终输出到添加的调试器,即使我们已在Release模式下进行了构建。根据MSDN文章:

Writes information about the debug to the trace listeners in the Listeners collection.

如果我们不需要任何输出,则需要使用DEBUG常量包装对Debug.Write的调用,如Juan所说:

#if DEBUG
    System.Diagnostics.Debug.Write(...);
#endif

回答

首选方法是实际使用条件属性包装调试调用,而不使用编译器指令。 #ifs可能会变得棘手,并可能导致奇怪的构建问题。

使用条件属性的示例如下(在C#中,但在VB.NET中也适用):

[ Conditional("Debug") ]
private void WriteDebug(string debugString)
{
  // do stuff
}

如果在未设置DEBUG标志的情况下进行编译,则与对Debug.Write()的假设一样,对WriteDebug的所有调用都将被删除。

回答

我也阅读了这篇文章,并且使我相信,当未定义DEBUG时,在System.Debug函数上声明的ConditionalAttribute会导致编译器完全忽略此代码。我认为TRACE同样适用。也就是说,System.Diagnostics.Debug函数必须具有DEBUG和TRACE的ConditionalAttributes。我的假设是错误的。单独的Trace类具有相同的功能,并且这些功能依赖于TRACE常量定义ConditionalAttribute。

从System.Diagnostics.Debug:
_
公开共享的子写(_
消息为字符串_
)

从System.Diagnostics.Trace:
_
公用共享子WriteLine(_
消息为字符串_
)

看来我最初的假设是正确的,System.Diagnostics.Debug(或者system.Diagnostics.Trace)语句实际上并未包含在编译中,就好像它们包含在#IF DEBUG(或者#IF TRACE)区域中一样。

但是我在这里也从你们那里了解到并验证,RELEASE构建本身并不能解决这个问题。至少对于Silverlight项目而言,它仍然有些不稳定,我们需要进入" Advanced Compile Options ...",并确保未定义DEBUG。

我们从.NET 1.1 / VS2003跳到了.NET 3.5 / VS2008,因此我认为其中某些功能以前的工作方式有所不同,但也许在2.0 / VS2005中有所改变。

回答

检查Debug.Write方法。标有

[Conditional("DEBUG")]

属性。

MSDN帮助中的ConditionalAttribute指出:

Indicates to compilers that a method
  call or attribute should be ignored 
  unless a specified conditional
  compilation symbol is defined.

构建配置是否带有发布标签或者调试标签并不重要,重要的是是否在其中定义了DEBUG符号。

回答

要选择是要编译还是要删除调试信息,

在项目的属性窗口中输入"构建"标签。

选择正确的配置(活动/发布/调试/全部),并确保我们
如果需要此信息,请检查"调试常量",
否则,请取消选中它。

应用更改并重建