555

In Solution properties, I have Configuration set to "release" for my one and only project.

At the beginning of the main routine, I have this code, and it is showing "Mode=Debug". I also have these two lines at the very top:

#define DEBUG 
#define RELEASE

Am I testing the right variable?

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

My goal is to set different defaults for variables based on debug vs release mode.

1
  • 14
    You are defining BOTH debug and release. Commented Jan 20, 2010 at 19:05

15 Answers 15

914

DEBUG/_DEBUG should be defined in VS already.

Remove the #define DEBUG in your code. Set preprocessors in the build configuration for that specific build.

The reason it prints "Mode=Debug" is because of your #define and then skips the elif.

The right way to check is:

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

Don't check for RELEASE.

6
  • 89
    I wanted to add that if one only wanted to check for RELEASE then one can do this: #if !DEBUG
    – user152949
    Commented Mar 3, 2012 at 9:44
  • 5
    Why #if and not #ifdef?
    – Bob Stein
    Commented May 29, 2014 at 14:04
  • 28
    @BobStein-VisiBone Remember we are talking about C# here, not C. #ifdef is specific to the preprocessor of C/C++, C# mandates the use of #if. Commented Jul 9, 2014 at 11:41
  • 28
    @Jess, I believe this is Visual Studio doing the greying out, not ReSharper Commented Sep 17, 2015 at 21:33
  • 3
    How does one "Set preprocessors"?
    – Demodave
    Commented Oct 20, 2016 at 18:55
368

By default, Visual Studio defines DEBUG if project is compiled in Debug mode and doesn't define it if it's in Release mode. RELEASE is not defined in Release mode by default. Use something like this:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif

If you want to do something only in release mode:

#if !DEBUG
  // release...
#endif

Also, it's worth pointing out that you can use [Conditional("DEBUG")] attribute on methods that return void to have them only executed if a certain symbol is defined. The compiler would remove all calls to those methods if the symbol is not defined:

[Conditional("DEBUG")]
void PrintLog() {
    Console.WriteLine("Debug info");
}

void Test() {
    PrintLog();
}
0
296

I prefer checking it like this over looking for #define directives:

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

With the caveat that of course you could compile and deploy something in debug mode but still not have the debugger attached.

13
  • 3
    Thank you! I don't yet even know what "#defines" are so this is a great solution!
    – Tim
    Commented Feb 8, 2012 at 10:29
  • And im my case, this does exactly what I want. I actually want to know if I have a debugger attached, because I know I have some code I do not want executed if I have a debugger attached. This is awesome!
    – JFTxJ
    Commented Aug 13, 2013 at 15:01
  • 1
    If personally like using #IF DEBUG in situation of debugging code that shouldn't last. For production code I agree with using the above.
    – Paul C
    Commented Nov 20, 2013 at 12:59
  • 28
    The draw back to doing this instead of using #DEBUG is that this if statement is in your code and always checked where as the #DEBUG answer removes the code that isn't applicable at compile time so you don't have a run-time check and your .exe (or whatever you compile to) is smaller.
    – Dan
    Commented Aug 22, 2014 at 22:44
  • 3
    @user34660. The answer to the stated question is "no", which doesn't really help anyone. Commented Aug 16, 2019 at 13:24
67

I'm not a huge fan of the #if stuff, especially if you spread it all around your code base as it will give you problems where Debug builds pass but Release builds fail if you're not careful.

So here's what I have come up with (inspired by #ifdef in 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;
    }
}
7
  • 3
    Hey now, that's pretty creative. I like your use of the attribute to set the property.
    – kenchilada
    Commented Mar 30, 2013 at 0:45
  • 6
    This has the advantage of not getting hit by refactoring bugs in Resharper that can mess up your code based on the current conditional setup.
    – Jafin
    Commented Apr 1, 2013 at 23:45
  • 3
    I like this but i am wondering why not create a singleton implementation for this instead of a service. It's system specific and it stops you having to worry about injecting it everywhere. (can you envisage a scenario where the implementation of this functionality would be any different? Commented Jan 22, 2015 at 8:41
  • 1
    I actually have a singleton and service implementation in one class that I'm using now so you get to have the choice of which way to use it... Of course the service implementation has the benefit of being easier to "stub" out so that you can test both code paths... Commented Jan 23, 2015 at 0:42
  • 2
    I am wondering why DebuggingService is not a static class and why you need an interface? Is this something to do with using this with an IoC container?
    – Ben
    Commented Apr 6, 2016 at 15:32
34
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

The method Debug.Assert has conditional attribute DEBUG. If it is not defined, the call and the assignment isDebug = true are eliminated:

If the symbol is defined, the call is included; otherwise, the call (including evaluation of the parameters of the call) is omitted.

If DEBUG is defined, isDebug is set to true (and passed to Debug.Assert , which does nothing in that case).

2
  • This is also a pretty creative solution. :)
    – Jack
    Commented May 22, 2016 at 1:48
  • Nice. For an iteration variable that needs to change between Debug and Release... var iterations = 10; Debug.Assert((iterations = Int32.MaxValue) > 0);
    – Matt Davis
    Commented Apr 7, 2019 at 1:08
22

If you are trying to use the variable defined for the build type you should remove the two lines ...

#define DEBUG  
#define RELEASE 

... these will cause the #if (DEBUG) to always be true.

Also there isn't a default Conditional compilation symbol for RELEASE. If you want to define one go to the project properties, click on the Build tab and then add RELEASE to the Conditional compilation symbols text box under the General heading.

The other option would be to do this...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif
15

Be sure to define the DEBUG constant in the Project Build Properties. This will enable the #if DEBUG. I don't see a pre-defined RELEASE constant, so that could imply that anything Not in a DEBUG block is RELEASE mode.

Define DEBUG constant in Project Build Properties

9

NameSpace

using System.Resources;
using System.Diagnostics;

Method

   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;
    }
8

Remove your defines at the top

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif
8

Slightly modified (bastardized?) version of the answer by Tod Thomson as a static function rather than a separate class (I wanted to be able to call it in a WebForm viewbinding from a viewutils class I already had included).

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}
8

It is worth noting here that one of the most significant differences between conditionally executing code based on #if DEBUG versus if(System.Diagnostics.Debugger.IsAttached) is that the compiler directive changes the code that is compiled. That is, if you have two different statements in an #if DEBUG/#else/#endif conditional block, only one of them will appear in the compiled code. This is an important distinction because it allows you do do things such as conditionally compile method definitions to be public void mymethod() versus internal void mymethod() depending on build type so that you can, for example, run unit tests on debug builds that will not break access control on production builds, or conditionally compile helper functions in debug builds that will not appear in the final code if they would violate security in some way should they escape into the wild. The IsAttached property, on the other hand, does not affect the compiled code. Both sets of code are in all of the builds - the IsAttached condition will only affect what is executed. This by itself can present a security issue.

5

A tip that may save you a lot of time - don't forget that even if you choose debug under the build configuration (on vs2012/13 menu it's under BUILD => CONFIGURATION MANAGER) - that's not enough.

You need to pay attention to the PUBLISH Configuration, as such:

enter image description here

0

I got to thinking about a better way. It dawned on me that #if blocks are effectively comments in other configurations (assuming DEBUG or RELEASE; but true with any symbol)

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");
        }
0

Remove the definitions and check if the conditional is on debug mode. You do not need to check if the directive is on release mode.

Something like this:

#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif
-1

Since the purpose of these COMPILER directives are to tell the compiler NOT to include code, debug code,beta code, or perhaps code that is needed by all of your end users, except say those the advertising department, i.e. #Define AdDept you want to be able include or remove them based on your needs. Without having to change your source code if for example a non AdDept merges into the AdDept. Then all that needs to be done is to include the #AdDept directive in the compiler options properties page of an existing version of the program and do a compile and wa la! the merged program's code springs alive!.

You might also want to use a declarative for a new process that is not ready for prime time or that can not be active in the code until it's time to release it.

Anyhow, that's the way I do it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.