Removing code from Release build in .NET - c#

I've been doing some performance testing around the use of System.Diagnostics.Debug, and it seems that all code related to the static class Debug gets completely removed when the Release configuration is built. I was wondering how the compiler knows that. Maybe there is some class or configuration attribute that allows to specify exactly that behavior.
I am trying to create some debugging code that I want completely removed from the Release configuration, and I was wondering if I could do it just like the Debug class where simply changing the configuration parameters removes the code.

You can apply the ConditionalAttribute attribute, with the string "DEBUG" to any method and calls to that item will only be present in DEBUG builds.
This differs from using the #ifdef approach as this allows you to release methods for use by other people in their DEBUG configurations (like the Debug class methods in the .NET framework).

Visual Studio defines a DEBUG constant for the Debug configuration and you can use this to wrap the code that you don't want executing in your Release build:
#ifdef DEBUG
// Your code
#endif
However, you can also decorate a method with a Conditional attribute, meaning that the method will never be called for non-Debug builds (the method and any call-sites will be removed from the assembly):
[Conditional("DEBUG")]
private void MyDebugMethod()
{
// Your code
}

Have a look at preprocessor directives...
#if DEBUG
//code
#endif

Related

In C#, is a Debug.Assert test run in release mode?

Take the following example:
public void Foo()
{
//Code...
Debug.Assert(ExpensiveTest());
//Code...
}
What happens to the the Debug.Assert method when I compile in release mode? Would ExpensiveTest() still run? If not, then how does it work (since it is not a macro that can be set to evaluate to nothing)? If it does run, then doesn't that defeat the purpose of debug assertions?
What happens to the the Debug.Assert method when I compile in release mode?
It's completely removed (including the call to ExpensiveTest), assuming you don't have the DEBUG conditional compilation symbol defined in your release configuration.
If you look at the documentation, the declaration uses [ConditionalAttribute("DEBUG")]:
[ConditionalAttribute("DEBUG")]
public static void Assert(
bool condition
)
ConditionalAttribute is used for conditional compilation. See Bart de Smet's blog post on conditional compilation for more details, along with section 17.4.2 of the C# 4 specification.
Assertions in Managed Code - MSDN
In Visual Basic and Visual C#, you can use the Assert method from
either Debug or Trace, which are in the System.Diagnostics namespace.
Debug class methods are not included in a Release version of your program, so they do not increase the size or reduce the speed of
your release code.
Also from the same link:
Note that calls to the Debug.Assert method disappear when you create
a Release version of your code. That means that the call that checks
the balance disappears in the Release version. To solve this problem,
you should replace Debug.Assert with Trace.Assert, which does not
disappear in the Release version
According to Debug.Assert Method (Boolean) Debug methods are compiled only in debug builds.
So, it you build correct release build (see menu item Debug/Configuration Manager for details) this method call will be removed.
Q. In C#, is a Debug.Assert test run in release mode?
The answer is "No." From Microsoft support: How to trace and debug in Visual C#:
You can use the Trace and the Debug classes separately or
together in the same application. In a Debug Solution Configuration
project, both Trace and Debug output are active. The project
generates output from both of these classes to all Listener
objects. However, a Release Solution Configuration project only
generates output from a Trace class. The Release Solution
Configuration project ignores any Debug class method invocations.
In particular, the last sentence makes it clear that Debug.Assert() statements (as well as other Debug class method invocations) are ignored in a Release build.

How can I mark some lines of my code as it won't run in release?

I want to throw exceptions while debugging but in release mode I don't want to throw them. I am logging them into EventLog. This is the source of my problem but if I'm not wrong in C and Delphi there are some directives to make this.
In C# is there any way(directives or something else) which can ignore the lines in debug mode or release mode?
You can do it like this:
#if DEBUG
Console.WriteLine("Debug version");
#endif
http://msdn.microsoft.com/en-us/library/4y6tbswk.aspx
For your purposes (logging), you might also be interested in the ConditionalAttribute. It lets you mark an entire method as "remove all calls to this method in release builds".
If you do your logging in a lot of different places in your code, this would be much simpler than adding #if DEBUG around every single call site.
Use the #if DEBUG directive (and end with #endif). The DEBUG constant is defined when you run your application in debug mode (the Define DEBUG constant should be checked under the Build tab of your project properties).

C# Do Debug statements get compiled out when running in Release mode?

It seems like it would be ideal (in terms of readability) to use say Debug.WriteLine to write to output rather than a ton of #if DEBUG statements.
When the program is compiled in release mode, does all the overhead with the Debug.WriteLine go away as if it did not exist, or is the function still called, but nothing done internally?
If so, is there any way to obtain this functionality on a custom class, i.e., a static call would only be compiled in if we are in Debug mode?
It is called ConditionalAttribute and it is already there: Debug.WriteLine() calls are removed entirely when you compile in Release mode.
It is declared like this:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string message)
So any calls to it are removed if the DEBUG symbol is not declared, e.g., in the default configuration of a release build. (You can change what pre-processor symbols are defined for different build configurations in the project properties.)
The same is true for (almost?) every method in Debug. In fact, it is the main difference between Debug and Trace - Trace's methods stay in release also.

Preprocessor in C# is not working correctly

#if(DEBUG)
......Code......
#else
......Code......
#endif
I have some code like this. If my application is running in Debug mode it should execute the #if(DEBUG) part, if it is running in Release mode it should execute the #else part. However, it is only executing the #if(DEBUG) part no matter which mode it is running in.
Am using WPF application with VS2010
Can anyone help me?
For Debug Configuration, your project settings should look like
For Release they should look like this
Can you verify that this is the case, and let us know if it is?
If not, what is there for each configuration?
Create a new project using all the default settings and check that you can make that work as expected. If so, your problem project must be "corrupted" in some way, perhaps by defining the DEBUG constant in the release configuration, or by having the debug project configuration selected for the release solution configuration.
It depends on how you create your configurations. For example if you create your configuration and use debug or release as a template DEBUG or RELEASE will be copied to the defined constraints element. It will not change the defined constraints element (in the project file) to the new configuration name.
Open up the project file and look for the configuration sections. Make sure the Platform, the below example it is "PROD" has an entry in the DefineConstants element. If it does the pre-compiler directives will don't work as expected in the code.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PROD|x86'">
<DefineConstants>PROD;TRACE</DefineConstants>
<OutputPath>bin\x86\PROD\</OutputPath>
</PropertyGroup>
Why are you putting DEBUG between parentheses?
#if DEBUG
Code
#else
Code
#endif
I would guess that in your project properties, under Build you have checked off Define DEBUG constant.
Try setting configuration mode to Release and run your application again. Default for Release is that the DEBUG constant is not defined, if you haven't tampered with if of course ;)
If Define DEBUG constant is not checked, that means you have a #define DEBUG lurking somewhere.
So two things to do. Check constant in options under Release mode, and check for any manually defined constant. It should be one of those.

How can I easily exclude certain lines of code from a compile?

Scattered throughout a software project I am working on are many lines of code that were written for debugging and utility purposes. Before I compile my code, I want a way to select whether or not these blocks of code should be included into my compile (something that won't require navigating the code commenting out). How can I do this?
I'm programming in c# and using Microsoft Visual Studio 2010.
Add the attribute [Conditional("DEBUG")] onto methods you only want to have execute in your debug build. See here for more detailed information.
I would suggest enclosing your blocks in #ifdef SOMETHING and #endif, and then defining SOMETHING in your project settings when you want to include that block in your compile.
You need preprocessor directives, or conditional compile statements. You can read about them here.
An example from that link:
#define TEST
using System;
public class MyClass
{
public static void Main()
{
#if (TEST)
Console.WriteLine("TEST is defined");
#else
Console.WriteLine("TEST is not defined");
#endif
}
}
The code is only compiled if TEST is defined at the top of the code. A lot of developers use #define DEBUG so they can enable debugging code and remove it again just by altering that one line at the top.
Consider using the Debug class to conditionally log, assert, etc. There are many advantages to this. You can choose to log (or not) at runtime. They limit you to (mostly) non-behavior-changing actions, addressing some of #STW's (valid) concern. They allow the use of third-party logging tools.
If they are for debugging, then the only acceptable solution is to surround such code with:
#ifdef DEBUG
#endif
This ensures that the code is included when you compile in debug mode but excluded in release mode.
You can use preprocessor directives w/ #if
You may want to consider moving these debugging functions out of the classes entirely--having your classes "change shape" between Debug and Release mode can be a real headache and can be difficult to diagnose problems.
You could consider creating a seperate "Debug" assembly which contains all your debugging helpers--then just make sure you can exclude it from the solution and build successfully without it.

Categories