C#if / thendebuggingvs发布指令
在解决scheme的属性,我有configuration设置为“释放”我的唯一的项目。
在主例程的开始,我有这个代码,它显示“Mode = Debug”。 我也有这两条线:
#define DEBUG #define RELEASE
我正在testing正确的variables?
#if (DEBUG) Console.WriteLine("Mode=Debug"); #elif (RELEASE) Console.WriteLine("Mode=Release"); #endif
我的目标是根据debuggingvs释放模式为variables设置不同的默认值。
删除代码中的#define DEBUG
。 在特定版本的构buildconfiguration中设置预处理器(DEBUG / _DEBUG应该已经在VS中定义)。
打印“Mode = Debug”的原因是因为你的#define
,然后跳过elif
。
另外,检查的正确方法是:
#if DEBUG Console.WriteLine("Mode=Debug"); #else Console.WriteLine("Mode=Release"); #endif
不要检查RELEASE
默认情况下,如果项目是以“debugging”模式编译的,Visual Studio会定义DEBUG,如果它处于“发行”模式下,则不定义该项目。 版本在默认情况下未在发行模式中定义。 使用这样的东西:
#if DEBUG // debug stuff goes here #else // release stuff goes here #endif
如果您只想在发布模式下执行某些操作:
#if !DEBUG // release... #endif
另外,值得指出的是,对于返回void
方法,可以使用[Conditional("DEBUG")]
属性,只有在定义了某个符号的情况下才会执行它们。 如果未定义符号,编译器将删除对这些方法的所有调用:
[Conditional("DEBUG")] void PrintLog() { Console.WriteLine("Debug info"); } void Test() { PrintLog(); }
我喜欢像这样检查它,并寻找#defines:
if (System.Diagnostics.Debugger.IsAttached) { //... } else { //... }
当然,您可以在debugging模式下编译和部署某些东西,但仍然没有附加debugging器。
我不是#if东西的巨大粉丝,尤其是如果你把它散布在你的代码基础上,因为它会给你在Debug构build通过的地方带来问题,但是如果你不小心的话,Release构build失败。
所以这就是我所想到的(受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; } }
如果您正尝试使用为构buildtypes定义的variables,则应删除两行…
#define DEBUG #define RELEASE
…这些将导致#if(DEBUG)始终为真。
另外, RELEASE不存在默认的条件编译符号。 如果要定义一个转到项目属性,请单击“ 生成”选项卡,然后将RELEASE添加到“ 常规”标题下的“ 条件编译符号”文本框中。
另一个select是做这个…
#if DEBUG Console.WriteLine("Debug"); #else Console.WriteLine("Release"); #endif
bool isDebug = false; Debug.Assert(isDebug = true); // '=', not '=='
Debug.Assert
方法具有条件属性DEBUG
。 如果没有定义,调用和赋值 isDebug = true
被消除 :
如果定义了符号,则包含呼叫; 否则,呼叫(包括呼叫参数的评估)被省略。
如果DEBUG
被定义, isDebug
被设置为true
(并传递给Debug.Assert
,在这种情况下什么都不做)。
删除顶部的定义
#if DEBUG Console.WriteLine("Mode=Debug"); #else Console.WriteLine("Mode=Release"); #endif
由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; }
命名空间
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; }
一个可以节省大量时间的小技巧 – 不要忘记,即使您在构buildconfiguration下select了debug
(在vs2012 / 13菜单下它在BUILD => CONFIGURATION MANAGER下),这还不够。
您需要注意PUBLISH Configuration
,如下所示:
由于这些COMPILER指令的目的是告诉编译器不要包含所有最终用户所需的代码,debugging代码,testing代码或者代码,除了那些广告部门,例如#Define AdDept,你想要能够根据您的需求包括或删除它们。 如果例如非AdDept合并到AdDept中,则无需更改源代码。 然后,所有需要做的事情就是将#AdDept指令包含在现有程序版本的编译器选项属性页中,并进行编译并执行。 合并的程序的代码弹簧活着!
您可能还想使用一个声明式的方法来处理尚未准备好的新进程,或者在代码释放之前无法在代码中处于活动状态。
总之,就是这样做的。