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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2104099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:31:05  来源:igfitidea点击:

C# if/then directives for debug vs release

c#debuggingreleasecompiler-directives

提问by NealWalters

In Solution properties, I have Configuration set to "release" for my one and only project.

在解决方案属性中,我将我的一个且唯一的项目的配置设置为“发布”。

At the beginning of the main routine, I have this code, and it is showing "Mode=Debug". I also have these two lines at the very top:

在主程序的开头,我有这个代码,它显示“模式=调试”。我在最顶部也有这两行:

#define DEBUG 
#define RELEASE

Am I testing the right variable?

我在测试正确的变量吗?

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

My goal is to set different defaults for variables based on debug vs release mode.

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

采纳答案by psychotik

DEBUG/_DEBUGshould be defined in VS already.

DEBUG/_DEBUG应该已经在 VS 中定义了。

Remove the #define DEBUGin your code. Set preprocessors in the build configuration for that specific build.

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

The reason it prints "Mode=Debug" is because of your #defineand then skips the elif.

它打印“Mode = Debug”的原因是因为您#define然后跳过elif.

The right way to check is:

正确的检查方法是:

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

Don't check for RELEASE.

不要检查RELEASE.

回答by Matthew Whited

If you are trying to use the variable defined for the build type you should remove the two lines ...

如果您尝试使用为构建类型定义的变量,则应删除这两行...

#define DEBUG  
#define RELEASE 

... these will cause the #if (DEBUG)to always be true.

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

Also there isn't a default Conditional compilation symbol for RELEASE. If you want to define one go to the project properties, click on the Buildtab and then add RELEASE to the Conditional compilation symbolstext box under the Generalheading.

RELEASE也没有默认的条件编译符号。如果要定义一个转到项目属性,请单击“构建”选项卡,然后将 RELEASE 添加到“常规”标题下的“条件编译符号”文本框。

The other option would be to do this...

另一种选择是这样做......

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

回答by Mehrdad Afshari

By default, Visual Studio defines DEBUG if project is compiled in Debug mode and doesn't define it if it's in Release mode. RELEASE is not defined in Release mode by default. Use something like this:

默认情况下,如果项目在调试模式下编译,Visual Studio 定义 DEBUG,如果项目在发布模式下不定义它。默认情况下,在 Release 模式下未定义 RELEASE。使用这样的东西:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif

If you want to do something only in release mode:

如果你只想在发布模式下做一些事情:

#if !DEBUG
  // release...
#endif

Also, it's worth pointing out that you can use [Conditional("DEBUG")]attribute on methods that return voidto have them only executed if a certain symbol is defined. The compiler would remove all calls to those methods if the symbol is not defined:

此外,值得指出的是,您可以[Conditional("DEBUG")]在方法上使用属性,这些方法void仅在定义了某个符号时才执行。如果未定义符号,编译器将删除对这些方法的所有调用:

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

void Test() {
    PrintLog();
}

回答by McAden

Remove your defines at the top

删除顶部的定义

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

回答by Joel Coehoorn

I prefer checking it like this over looking for #definedirectives:

我更喜欢像这样检查它而不是寻找#define指令:

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

With the caveat that of course you could compile and deploy something in debug mode but still not have the debugger attached.

需要注意的是,您当然可以在调试模式下编译和部署某些东西,但仍然没有附加调试器。

回答by Ehsan Enaloo

NameSpace

命名空间

using System.Resources;
using System.Diagnostics;

Method

方法

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

回答by Tod Thomson

I'm not a huge fan of the #if stuff, especially if you spread it all around your code base as it will give you problems where Debug builds pass but Release builds fail if you're not careful.

我不是#if 东西的忠实粉丝,特别是如果你把它散布在你的代码库中,因为如果你不小心,它会给你带来调试构建通过但发布构建失败的问题。

So here's what I have come up with (inspired by #ifdef in C#):

所以这就是我想出的(灵感来自C# 中#ifdef):

public interface IDebuggingService
{
    bool RunningInDebugMode();
}

public class DebuggingService : IDebuggingService
{
    private bool debugging;

    public bool RunningInDebugMode()
    {
        //#if DEBUG
        //return true;
        //#else
        //return false;
        //#endif
        WellAreWe();
        return debugging;
    }

    [Conditional("DEBUG")]
    private void WellAreWe()
    {
        debugging = true;
    }
}

回答by mrMagik3805

Since the purpose of these COMPILER directives are to tell the compiler NOT to include code, debug code,beta code, or perhaps code that is needed by all of your end users, except say those the advertising department, i.e. #Define AdDept you want to be able include or remove them based on your needs. Without having to change your source code if for example a non AdDept merges into the AdDept. Then all that needs to be done is to include the #AdDept directive in the compiler options properties page of an existing version of the program and do a compile and wa la! the merged program's code springs alive!.

由于这些编译器指令的目的是告诉编译器不要包含所有最终用户所需的代码、调试代码、测试版代码或可能的代码,除了广告部门,即您想要的#Define AdDept能够根据您的需要包含或删除它们。例如,如果非 AdDept 合并到 AdDept,则无需更改您的源代码。然后需要做的就是在现有版本程序的编译器选项属性页面中包含#AdDept 指令,然后进行编译和哇啦!合并后的程序代码活跃起来!

You might also want to use a declarative for a new process that is not ready for prime time or that can not be active in the code until it's time to release it.

您可能还想对尚未准备好迎接黄金时段的新流程或在发布之前无法在代码中处于活动状态的新流程使用声明。

Anyhow, that's the way I do it.

无论如何,这就是我的方式。

回答by AlexD

bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

The method Debug.Asserthas conditional attribute DEBUG. If it is not defined, the call and the assignmentisDebug = trueare eliminated:

该方法Debug.Assert具有条件属性DEBUG。如果未定义,则取消调用和分配isDebug = true

If the symbol is defined, the call is included; otherwise, the call (including evaluation of the parameters of the call) is omitted.

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

If DEBUGis defined, isDebugis set to true(and passed to Debug.Assert, which does nothing in that case).

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

回答by LocalPCGuy

Slightly modified (bastardized?) version of the answer by Tod Thomson as a static function rather than a separate class (I wanted to be able to call it in a WebForm viewbinding from a viewutils class I already had included).

Tod Thomson 对答案的轻微修改(混蛋?)版本作为静态函数而不是单独的类(我希望能够在我已经包含的 viewutils 类的 WebForm 视图绑定中调用它)。

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}