C# If/Then Directives for Debug VS Release

C# if/then directives for debug vs release

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.

#if DEBUG vs. Conditional( DEBUG )

It really depends on what you're going for:

  • #if DEBUG: The code in here won't even reach the IL on release.
  • [Conditional("DEBUG")]: This code will reach the IL, however calls to the method will be omitted unless DEBUG is set when the caller is compiled.

Personally I use both depending on the situation:

Conditional("DEBUG") Example: I use this so that I don't have to go back and edit my code later during release, but during debugging I want to be sure I didn't make any typos. This function checks that I type a property name correctly when trying to use it in my INotifyPropertyChanged stuff.

[Conditional("DEBUG")]
[DebuggerStepThrough]
protected void VerifyPropertyName(String propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}",
GetType(), propertyName));
}

You really don't want to create a function using #if DEBUG unless you are willing to wrap every call to that function with the same #if DEBUG:

#if DEBUG
public void DoSomething() { }
#endif

public void Foo()
{
#if DEBUG
DoSomething(); //This works, but looks FUGLY
#endif
}

versus:

[Conditional("DEBUG")]
public void DoSomething() { }

public void Foo()
{
DoSomething(); //Code compiles and is cleaner, DoSomething always
//exists, however this is only called during DEBUG.
}

#if DEBUG example: I use this when trying to setup different bindings for WCF communication.

#if DEBUG
public const String ENDPOINT = "Localhost";
#else
public const String ENDPOINT = "BasicHttpBinding";
#endif

In the first example, the code all exists, but is just ignored unless DEBUG is on. In the second example, the const ENDPOINT is set to "Localhost" or "BasicHttpBinding" depending on if DEBUG is set or not.


Update: I am updating this answer to clarify an important and tricky point. If you choose to use the ConditionalAttribute, keep in mind that calls are omitted during compilation, and not runtime. That is:

MyLibrary.dll

[Conditional("DEBUG")]
public void A()
{
Console.WriteLine("A");
B();
}

[Conditional("DEBUG")]
public void B()
{
Console.WriteLine("B");
}

When the library is compiled against release mode (i.e. no DEBUG symbol), it will forever have the call to B() from within A() omitted, even if a call to A() is included because DEBUG is defined in the calling assembly.

Will #if RELEASE work like #if DEBUG does in C#?

No, it won't, unless you do some work.

The important part here is what DEBUG really is, and it's a kind of constant defined that the compiler can check against.

If you check the project properties, under the Build tab, you'll find three things:

  • A text box labelled "Conditional compilation symbols"
  • A check box labelled "Define DEBUG constant"
  • A check box labelled "Define TRACE constant"

There is no such checkbox, nor constant/symbol pre-defined that has the name RELEASE.

However, you can easily add that name to the text box labelled Conditional compilation symbols, but make sure you set the project configuration to Release-mode before doing so, as these settings are per configuration.

So basically, unless you add that to the text box, #if RELEASE won't produce any code under any configuration.

#if preprocessor directive for directives other than DEBUG

It's the same as for DEBUG, assuming that you've defined a build configuration that lists TEST in the "Conditional compilation symbols" text box (under project properties > Build tab; this is a space-delimited list).

For code that you only want to run in the TEST build configuration:

#if TEST
// ...
#endif

And for code you don't want to run in the TEST build configuration, you can either #else the above, or do this:

#if !TEST
// ...
#endif

How to run some code based on release or debug build mode?

From your question, you can use that:

/// <summary>
/// Indicate if the executable has been generated in debug mode.
/// </summary>
static public bool IsDebugExecutable
{
get
{
bool isDebug = false;
CheckDebugExecutable(ref isDebug);
return isDebug;
}
}

[Conditional("DEBUG")]
static private void CheckDebugExecutable(ref bool isDebug)
=> isDebug = true;

Of course you can swap name to:

IsReleaseExecutable

return !isDebug;

This approach implies that all code is compiled. Thus any code can be executed depending on this flag as well as any other behavior parameter concerning the user or the program, such as for example the activation or the deactivation of a debugging and tracing engine. For example:

if ( IsDebugExecutable || UserWantDebug )  DoThat();

Else a preprocessor directive like this:

C# if/then directives for debug vs release

#if DEBUG vs. Conditional("DEBUG")

When #if DEBUG runs

#if DEBUG It's a preprocessor definition.

It compiles when you define DEBUG constant. And yes, it's default on Debug Build Configuration.

Visual Studio 2010 Project Properties:
Visual Studio 2010 Project Properties

If Define DEBUG constant is checked VS will compile:

private const string BASE_URL = "http://www.a.com/";

Else (not checked) VS will compile:

private const string BASE_URL = "http://www.b.com//";

DEBUG vs RELEASE and distributing Assembly


If other developers reference my Assembly from their project and run their project in Debug mode, will my Debug only conditional run or not ?

No, because the Console.WriteLine() was never compiled in Release mode due to the pre-processor constraint.

MSDN has more to say on this:

When the C# compiler encounters an #if directive, followed eventually by an #endif directive, it will compile the code between the directives only if the specified symbol is defined ... Tell me more...

Also, it's not correct to think of it as being removed from the assembly as it was never present in the first place.

#if DEBUG directive in compiled class library

A compiler directive is interpreted at compile time and not at runtime. Therefore it does not matter, if the using application is compiled in RELEASE or DEBUG mode. Therefore

1.) library is compiled in DEBUG mode, application is compiled in RELEASE => Yes

2.) library is compiled in RELEASE, application is compiled in DEBUG => No



Related Topics



Leave a reply



Submit