C#如果/则的指令对于"调试"vs释放
-
21-09-2019 - |
题
在解决方案的性质,我已配置"释放"我的唯一项目。
在开始主程序,我有这样的代码,它是表示"Mode=调试"。我也有这两条路线在很顶:
#define DEBUG
#define RELEASE
我测试正确的变量?
#if (DEBUG)
Console.WriteLine("Mode=Debug");
#elif (RELEASE)
Console.WriteLine("Mode=Release");
#endif
我的目标是设置不同的默认基于变量在调试vs释放模式。
解决方案
在代码中取出#define DEBUG
。在该特定的构建构建配置集合的预处理器(DEBUG / _DEBUG应当在VS已定义)。
它打印“模式=调试”的原因是因为你的#define
,然后跳过elif
。
此外,为了检查正确的方式是:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
不检查RELEASE
其他提示
默认情况下,Visual Studio中,如果项目在调试模式下编译,如果它在释放模式不定义它定义了DEBUG。释放不是在Release模式默认定义。使用这样的:
#if DEBUG
// debug stuff goes here
#else
// release stuff goes here
#endif
如果您希望只在释放模式做一些事情:
#if !DEBUG
// release...
#endif
此外,值得指出的是,你可以在方法,返回[Conditional("DEBUG")]
有如果某个符号的定义仅他们执行使用void
属性。如果没有定义的符号,编译器将移除这些方法的所有调用:
[Conditional("DEBUG")]
void PrintLog() {
Console.WriteLine("Debug info");
}
void Test() {
PrintLog();
}
我更喜欢检查它像这样VS寻找#定义:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
需要提醒的是,当然,你可以编译和部署的东西在调试模式,但仍然没有调试器连接。
我不是的东西#如果一个巨大的风扇,特别是如果你传播它周围的所有代码库,因为它会给你的问题在那里调试版本通过,但发布版本,如果你不小心失败。
因此,这里就是我想出了(由的#ifdef在C#启发一>):
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;
}
}
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
该方法 Debug.Assert
有条件的属性 DEBUG
.如果这不是定义,呼叫 和分配 isDebug = true
都 消除:
如果符号被定义,该呼叫中包含的;否则,呼吁(包括评估参数的话)是省略。
如果 DEBUG
定义, isDebug
被设定为 true
(并传递到 Debug.Assert
,这并没有什么在这种情况下)。
如果您要使用的生成类型定义的变量,你应该删除两行...
#define DEBUG
#define RELEASE
...这些将导致的#if(DEBUG)总是真的。
也有不是用于默认条件编译标志 RELEASE 。如果要定义一个转到项目属性,点击的构建的标签,然后添加释放到的条件编译符号的文本框下的常规航向。
另一种选择是做这...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
在顶部移除你定义
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
稍加修改(bastardized?)版本(我希望能够调用它在一个WebForm从viewutils类viewbinding我已经包括在内)。
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;
}
这可以为您节省大量的时间小费 - 不要忘了,即使你选择debug
构建配置下(vs2012 / 13菜单,正在接受BUILD =>配置管理器) - 这还不够。
您需要注意的发布Configuration
,因为这样的:
由于这些编译器指令的目的是告诉编译器不包括代码,调试代码,测试代码,或者是由所有最终用户所需的代码,只是说,这些广告部,即#DEFINE AdDept你希望能够包括或根据您的需要将其删除。而无需改变你的源代码,例如,如果一个非AdDept合并到AdDept。然后,所有需要做的需求是包括方案的现有版本的编译器选项属性页的#AdDept指令,并做了编译和WA啦!合并后的程序代码弹簧活着!
您可能还需要使用一个声明为一个新的过程,是不是准备好黄金时间或代码,不能活动,直到它的时间来释放它。
总之,这是我做的方式。
我得到一个更好的思维方式。它我明白了在其它配置中的#if块是有效评论(假设DEBUG
或RELEASE
;但与任何符号真)
public class Mytest
{
public DateTime DateAndTimeOfTransaction;
}
public void ProcessCommand(Mytest Command)
{
CheckMyCommandPreconditions(Command);
// do more stuff with Command...
}
[Conditional("DEBUG")]
private static void CheckMyCommandPreconditions(Mytest Command)
{
if (Command.DateAndTimeOfTransaction > DateTime.Now)
throw new InvalidOperationException("DateTime expected to be in the past");
}
删除的定义,并检查条件是调试模式。你并不需要检查,如果该指令是在释放模式。
像这样:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif