Reputation: 8663
I am busy making some optimizations to a app of mine, what is the cleanest way to check if the app is in DEBUG or RELEASE
Upvotes: 23
Views: 24470
Reputation: 904
I have found that the following is a reliable way to check if an assembly has been compiled in debug or release mode:
static bool IsDebug(Assembly assembly)
{
var debugAttr = assembly.GetCustomAttribute<DebuggableAttribute>();
if (debugAttr is null)
{
return false;
}
return (debugAttr.DebuggingFlags & DebuggableAttribute.DebuggingModes.Default) != 0;
}
To check if the current assembly has been compiled as such:
if (IsDebug(Assembly.GetExecutingAssembly()))
{
// ...
}
Using #if DEBUG
is the better way to check if the current assembly has been compiled in debug or release, but sometimes you want to check at run time rather than compile time...
Upvotes: 2
Reputation: 141
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 result (bool).
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 in the comments). For example, check the following implementation of a DebugInfo() method that allows you to inline code information into a logging facility easily:
/// <summary>
/// A wrapper for debugging information in 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("Warning 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 straightforward way to include the advantages of conditionals in a simple method without allowing its drawbacks crawl around the code.
Upvotes: 4
Reputation: 1350
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
}
Upvotes: 21
Reputation: 1263
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:
Upvotes: 6
Reputation: 124794
I tend to put something like the following in AssemblyInfo.cs:
#if DEBUG
[assembly: AssemblyConfiguration("Debug build")]
#else
[assembly: AssemblyConfiguration("Release build")]
#endif
Upvotes: 5
Reputation: 132424
static class Program
{
public static bool IsDebugRelease
{
get
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
Though, I tend to agree with itowlson.
Upvotes: 25
Reputation: 74832
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.
Upvotes: 30