Answers:
DEBUG
/ _DEBUG
应该已经在VS中定义了。
删除#define DEBUG
代码中的。在该特定构建的构建配置中设置预处理器。
打印“ Mode = Debug”的原因是由于您的原因#define
,然后跳过elif
。
正确的检查方法是:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
不要检查RELEASE
。
#if
不#ifdef
呢?
#ifdef
是特定于C / C ++的预处理器的,C#强制使用#if
。
默认情况下,如果项目是在Debug模式下编译的,则Visual Studio会定义DEBUG,而在Release模式下则不会定义它。默认情况下,未在发布模式下定义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();
}
我喜欢这样检查它而不是寻找#define
指令:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
有了警告,您当然可以在调试模式下编译和部署某些东西,但仍然没有附加调试器。
#IF DEBUG
在调试代码不应该持续的情况下使用。对于生产代码,我同意使用上述代码。
#DEBUG
是,此if语句位于您的代码中,并始终检查#DEBUG
答案是否删除了在编译时不适用的代码,因此您没有运行时检查和your。 exe(或您编译的任何文件)较小。
我不是#if东西的忠实拥护者,特别是如果将其分散在代码库中,因为如果您不小心,它将在Debug生成通过的地方给您带来问题,但是Release生成会失败。
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;
}
}
DebuggingService
不是静态类,为什么需要接口?这与将IoC容器一起使用有关吗?
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
该方法Debug.Assert
具有条件属性DEBUG
。如果未定义,则消除呼叫和分配 :isDebug = true
如果定义了该符号,则包括该呼叫;否则,将忽略该呼叫(包括对呼叫参数的评估)。
如果DEBUG
定义了if ,isDebug
则将其设置为true
(并传递给Debug.Assert
,在这种情况下不执行任何操作)。
var iterations = 10; Debug.Assert((iterations = Int32.MaxValue) > 0);
如果您尝试使用为构建类型定义的变量,则应删除两行...
#define DEBUG
#define RELEASE
...这些将导致#if(DEBUG)始终为true。
也没有RELEASE的默认条件编译符号。如果要定义一个转到项目属性,请单击“ 生成”选项卡,然后将“发布”添加到“ 常规”标题下的“ 条件编译符号”文本框中。
另一个选择是执行此操作...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("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;
}
由于这些COMPILER指令的目的是告诉编译器不要包括代码,调试代码,beta代码或所有最终用户所需的代码,除了广告部门(即您想要的#Define AdDept)外能够根据需要添加或删除它们。例如,如果非AdDept合并到AdDept中,则无需更改您的源代码。然后,所有需要做的就是在程序的现有版本的编译器选项属性页中包含#AdDept指令,并进行编译和警告!合并后的程序代码会自动运行!
您可能还想对新程序使用声明,而该声明在黄金时间还没有准备好,或者直到需要释放它时才在代码中处于活动状态。
无论如何,这就是我的方式。
我必须考虑一种更好的方法。我突然意识到#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