I put a lot of Debug.WriteLine in my code for debug purposes.
When I am ready to build for release, will these Debug.Write influence the release build, and where do they output to?
Debug.WriteLine is annotated with the Conditional attribute. (see MSDN)
The ConditionalAttribute tells the compiler not to generate that code unless the DEBUG flag is supplied.
From MSDN:
"The ConditionalAttribute attribute is applied to the methods of Debug. Compilers that support ConditionalAttribute ignore calls to these methods unless "DEBUG" is defined as a conditional compilation symbol. Refer to a compiler's documentation to determine whether ConditionalAttribute is supported and the syntax for defining a conditional compilation symbol."
So if your release configuration does not include DEBUG symbol the Debug.WriteLine calls will be omitted during compilation and there will be no output.
If you switch them to Trace.WriteLine you can define arbitrary listeners in the app/web.config file.
Debug.Writeline is not compiled into release code.
I believe it will be compiled out.
Related
I have c# application. The application includes resource file with images and icon.
My target is to compile the same application but with different set of images/icons. Same images name, but different content.
Is there a way to include different resource file in compile time on condition?
Maybe you are looking for Preprocessor Directives or Conditional Attribute.
Preprocessor directives
From this tutorial by Bipin Joshi:
C# preprocessor directives are commands that are meant for the C# compiler. Using preprocessor directives you instruct the C# compiler to alter the compilation process in some way. For example you may instruct the C# compiler that a particular block of code be excluded from the compilation process.
ConditionalAttribute
From MSDN
Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined.
To compare these two see this post.
I want to detect and report bugs in specific cases, using the same behavior as Debug.Assert(), but in a Release build. How can I do that?
You should be able to use Trace.Assert().
From MSDN:
Use the Trace.Assert method if you want to do assertions in release builds. The Debug.Assert method works only in debug builds.
You can manually add the DEBUG constant while still having Release optimizations enabled.
In the Build tab of your project settings just check the box that enables the DEBUG constant.
This allows all functions that have [ConditionalAttribute("DEBUG")] (like Assert()) to still function in your compiled program.
EDIT: Grant's answer is even better, if possible use Trace.Assert instead. That function triggers on if the constant TRACE is defined and it is defined by default in Release builds. That will make sure you don't get any unforeseen side effects of enabling any other code that uses #if DEBUG or [ConditionalAttribute("DEBUG")] in your code.
Can't you turn on Tracing and perform tracing? You can use conditional tracing in Release mode. Also, you can implement some conditionally logging with log4net
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.
I need to add some logging to my app, and it needs to be in release mode, and I need to make sure that the logging code isn't running in production. Therefore I'd like to use a #define and #if to make sure the log statements are removed when I move to production.
Trouble is, I need the logging in multiple files, and it's a pain to put a #define at the top of every file. Is there a way to have a centralized #define? That way I can remove the single #define rather than a #define from all files(which means I'll almost assuredly forget one).
On the command line, use the /define switch. In Visual Studio, choose the "Build" tab from the properties page for the project and fill in the "Conditional Compilation Symbols" section.
Consider also instead of using conditional compilation, to instead make your logging methods conditional methods. That's a more pleasant-looking alternative. That's how Debug.Assert works; it is a conditional method, so if the debug preprocessor symbol is not defined, the compiler simply removes all calls to the method before code generation.
See also my article on the subject:
http://ericlippert.com/2009/09/10/whats-the-difference-between-conditional-compilation-and-the-conditional-attribute/
Are you using Visual Studio? In the project Properties page, on the "Build" tab, there's a "Conditional compilation symbols" text box.
Yes, this is typically done in your build file, or the script you use which creates your build. You specify it as command-line arguments to MSBuild.
To add to Dave's answer, global conditional compilation symbols can also be specified in Visual.
Right-click on your project and go to Properties
Go to the Build tab
You can specify the symbols that you like (DEBUG is already turned on by default for Debug configurations, so this might actually give you what you want already) for the given configuration, or select "All Configurations" at the top to specify certain symbols for all configurations.
Call the logging everywhere you want.
Define the logging api entry methods with
[Conditional ("DEBUG")]
public void WriteDebugMessage(...)
Build your program in debug mode (which, by default, defines 'DEBUG' in VS). These calls will be part of your assembly.
Build your program in release mode (or - remove the DEBUG symbol from the build definition). These calls are now meaningless no-ops and won't run.
Seems like what you want?
I wonder how to compiler compile my code if I using #if directive inside my code.
I would like to create special version of my application (commercial demo version) and I want to limit the functionality of my application. I would rather avoid the obfuscation and just don't want to add all my compiled code to executable file. I need solution resists preview my code during disassembly process. Can I use #if directives for variant compilation instead making comments for disabling code parts?
Using the #if directive is like using the preprocessor in c++, in that the code would simply not be present if the condition hasn't been met (in compilation time). From MSDN:
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.
Unlike C and C++, you cannot assign a
numeric value to a symbol; the #if
statement in C# is Boolean and only
tests whether the symbol has been
defined or not.
As an addition to #ohadsc's answer: you can always check with Reflector what is actually produced by the compiler.