RC1140
RC1140

Reputation: 8663

How to check if a app is in debug or release

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

Answers (7)

Cillié Malan
Cillié Malan

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

AlessandroParma
AlessandroParma

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

ShrapNull
ShrapNull

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

Yohan
Yohan

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: enter image description here

Example 2: Compile as Debug mode: enter image description here

Upvotes: 6

to StackOverflow
to StackOverflow

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

Matthew Scharley
Matthew Scharley

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

itowlson
itowlson

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

Related Questions