I am busy making some optimizations to a app of mine, what is t开发者_JS百科he cleanest way to check if the app is in DEBUG or RELEASE
At compile time or runtime? At compile time, you can use #if DEBUG
. At runtime, you can use [Conditional("DEBUG")]
to indicate methods that should only be called in debug builds, but whether this will be useful depends on the kind of changes you want to make between debug and release builds.
static class Program
{
public static bool IsDebugRelease
{
get
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
Though, I tend to agree with itowlson.
Personally I don't like the way #if DEBUG
changes the layout. I do it by creating a conditional method that is only called when in debug mode and pass a boolean by reference.
[Conditional("DEBUG")]
private void IsDebugCheck(ref bool isDebug)
{
isDebug = true;
}
public void SomeCallingMethod()
{
bool isDebug = false;
IsDebugCheck(ref isDebug);
//do whatever with isDebug now
}
I tend to put something like the following in AssemblyInfo.cs:
#if DEBUG
[assembly: AssemblyConfiguration("Debug build")]
#else
[assembly: AssemblyConfiguration("Release build")]
#endif
You can use ILSpy both for exe and for dll. Just drag your DLL\EXE to the explorer sidebar and you can see at: [assembly: Debuggable line ....
Example 1: Compile as Release mode:
Example 2: Compile as Debug mode:
Even if the thread is old it may be useful to have a check programmatically. The test
if (Debugger.IsAttached)
{
}
checks at runtime if a Debugger is attached. The IsAttached property is static of the Debugger type so it is always providing a bool result.
The preprocessor directive #if DEBUG
is currently the fastest way to cut some code out (or throw it in) at compile time, but can be warning-prone when switching between release and debug compilation, especially when you define variables inside the block (at least i nthe comments). For example check the following implementation of a DebugInfo() method that allows you to inline into a logging facility easily:
/// <summary>
/// A wrapper for debugging information in the Serilog loggers.
/// Usage: Log.DebugInfo().Information(message)
/// Usage: Log.DebugInfo().Debug(message) etc.
/// </summary>
/// <param name="logger">
/// The Serilog Log to use.
/// </param>
/// <param name="memberName">
/// The name of the class calling the event log.
/// </param>
/// <param name="sourceFilePath">
/// The name of the file hosting the class.
/// </param>
/// <param name="sourceLineNumber">
/// the line in the source code file.
/// </param>
/// <returns>
/// </returns>
public static ILogger DebugInfo(this ILogger logger
#if DEBUG
// DebugInfo gets inline in release mode.
,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
#else
)
#endif
{
return logger
#if DEBUG
.ForContext("MemberName", memberName)
.ForContext("FilePath", Path.GetFileName(sourceFilePath))
.ForContext("LineNumber", sourceLineNumber)
#endif
;
}
}
can be called like this
Logger.DebugInfo().Warning("Warining message with a parameter in message template style: {Parameter}", _parameter);
to have some more information in the log files about the class and the code file that called the log line.
The solution would be to include also part of the XML comments into the conditionals, but that would render the whole unreadable.
After Hans note, yes it is pathologically possible that somebody may run a debug build outside VS. Then the static method proposed by Matthew IsDebugMode
is the most strightforward way to include the advantages of conditionals in a simple method without allowing its drawbacks crawl around the code.
精彩评论