调试与发布的C#if/then指令

调试与发布的C#if/then指令,c#,debugging,release,compiler-directives,C#,Debugging,Release,Compiler Directives,在解决方案属性中,我的唯一项目的配置设置为“release” 在主例程的开头,我有这段代码,它显示“Mode=Debug”。 我在最上面还有两行: #define DEBUG #define RELEASE 我测试的变量是否正确 #if (DEBUG) Console.WriteLine("Mode=Debug"); #elif (RELEASE) Console.WriteLine("Mode=Release"); #endif 我的目

在解决方案属性中,我的唯一项目的配置设置为“release”

在主例程的开头,我有这段代码,它显示“Mode=Debug”。 我在最上面还有两行:

#define DEBUG 
#define RELEASE
我测试的变量是否正确

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

我的目标是根据调试和发布模式为变量设置不同的默认值

如果试图使用为生成类型定义的变量,则应删除两行

#define DEBUG  
#define RELEASE 
。。。这些将导致#if(DEBUG)始终为真

此外,发布时没有默认的条件编译符号。如果要定义一个“转到项目属性”,请单击“生成”选项卡,然后将“发布”添加到“常规”标题下的“条件编译符号”文本框中

另一个选择是这样做

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif

默认情况下,VisualStudio在项目以调试模式编译时定义调试,而在项目处于发布模式时不定义调试。默认情况下,未在释放模式下定义释放。使用类似以下内容:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif
#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif
如果只想在发布模式下执行某些操作:

#if !DEBUG
  // release...
#endif
另外,值得指出的是,您可以对返回
void
的方法使用
[Conditional(“DEBUG”)]
属性,以便仅在定义了某个符号的情况下执行它们。如果未定义符号,编译器将删除对这些方法的所有调用:

[Conditional("DEBUG")]
void PrintLog() {
    Console.WriteLine("Debug info");
}

void Test() {
    PrintLog();
}

DEBUG
/
\u DEBUG
应已在VS中定义

删除代码中的
#define DEBUG
。在特定生成的生成配置中设置预处理器

它打印“Mode=Debug”的原因是因为您定义了
,然后跳过了
elif

正确的检查方法是:

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

不要检查
发布

删除顶部的定义

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif

与查找
#define
指令相比,我更喜欢这样检查:

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}
需要注意的是,您当然可以在调试模式下编译和部署某些东西,但仍然没有附加调试器。

using System.Resources;
using System.Diagnostics;
方法

   private static bool IsDebug()
    {
        object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
        if ((customAttributes != null) && (customAttributes.Length == 1))
        {
            DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
            return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
        }
        return false;
    }
我不太喜欢#if之类的东西,尤其是如果你把它散布在你的代码库中,因为如果你不小心的话,它会给你带来调试版本通过而发布版本失败的问题

以下是我的灵感:


因为这些编译器指令的目的是告诉编译器不要包含所有最终用户所需的代码、调试代码、测试版代码或可能的代码,除了广告部门所说的那些代码,即#Define addpt,您希望能够根据需要包含或删除它们。例如,如果一个非加法器合并到加法器中,则无需更改源代码。然后,需要做的就是在现有版本的程序的编译器选项属性页中包含#addpt指令,并进行编译和wa la!合并后的程序的代码将激活

您可能还希望对一个新流程使用声明性语句,该流程尚未准备就绪,或者在发布之前无法在代码中处于活动状态

不管怎样,我就是这样做的

bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
该方法具有条件属性
DEBUG
。如果未定义,则调用和分配为:

如果定义了符号,则包括呼叫;否则,将忽略调用(包括调用参数的评估)

如果定义了
DEBUG
,则将
isDebug
设置为
true
(并传递到
DEBUG.Assert
,在这种情况下,它不会执行任何操作)。

稍微修改了托德·汤姆森(Tod Thomson)的答案版本,将其作为一个静态函数,而不是单独的类(我希望能够从已经包含的viewutils类在WebFormViewBinding中调用它)


一个可能为您节省大量时间的提示—不要忘记,即使您在构建配置下选择了
debug
(在vs2012/13菜单上,它在build=>configurationmanager下),但这还不够

您需要注意发布
配置
,例如:


确保在项目生成属性中定义调试常量。这将启用
#if DEBUG
。我看不到预定义的释放常量,因此这可能意味着调试块之外的任何内容都是释放模式


我开始思考一种更好的方法。我突然意识到#如果块在其他配置中是有效的注释(假设
DEBUG
RELEASE
;但对于任何符号都是正确的)


删除定义并检查条件是否处于调试模式。无需检查指令是否处于发布模式

大概是这样的:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif
#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

这里值得注意的是,基于
#if DEBUG
的有条件执行代码与基于
if(System.Diagnostics.Debugger.IsAttached)的有条件执行代码之间最显著的区别之一
是指编译器指令更改编译的代码。也就是说,如果在一个
\if DEBUG/\else/#endif
条件块中有两个不同的语句,那么编译后的代码中只会出现一个语句。这是一个重要的区别,因为它允许您执行诸如condi之类的操作选择性地将方法定义编译为
公共void mymethod()
内部void mymethod()相比
取决于生成类型,例如,您可以在调试生成上运行单元测试,这些测试不会破坏对生产生成的访问控制,或者有条件地编译调试生成中的帮助函数,如果这些函数在某种程度上违反安全性,则不会出现在最终代码中。如果它们逃逸到野外,
将附加另一方面,de>属性不影响已编译的代码。这两组代码都在所有构建中,
IsAttached
condit
#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif