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:
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
Microsoft.Jet.Oledb.4.0' Provider Is Not Registered on the Local MAChine
What Is Hashcode Used For? Is It Unique
How to Clone/Deep Copy a .Net Generic Dictionary<String, T>
Calling Generic Method with a Type Argument Known Only at Execution Time
Equivalent to 'App.Config' for a Library (Dll)
Why Does This Async Action Hang When I Try and Access the Result Property of My Task
Accessing C# Anonymous Type Objects
Application.Openforms.Count = 0 Always
Wait Until File Is Completely Written
Serializing Private Member Data
Entity Framework Provider Type Could Not Be Loaded
Linq to SQL - Left Outer Join with Multiple Join Conditions
How to Read a Large (1 Gb) Txt File in .Net
C# Sort and Orderby Comparison
How to Pass Ienumerable List to Controller in MVC Including Checkbox State
Generic Methods in .Net Cannot Have Their Return Types Inferred. Why
How to Make an Event in the Usercontrol and Have It Handled in the Main Form