As I study and learn new things about PostSharp; which is a Postprocessor AOP tool. I figured I would write a little bit about preprocessors. In this series we will go over a few of the possible preprocessor directives available in .NET. The first few preprocessors that we will cover have been around since .NET 1.1/2.0.
So what is a preprocessor directive? As the name suggest they are a series of commands that are interpreted by the compiler at compile time. These commands may affect the output of the code as it compiles from (fill in your favorite .net language) to MSIL. The examples I will show in this series are done in C# but they should work fine any any MSIL based language.
A preprocessor is identified by the pound sign # followed by the directive name. The preprocessors covered in part 1 will be:
- #if
- #endif
- #else
The first directive is #if. When the compiler gets to this directive it will compile the code if the symbol has been defined. We will talk about defining customer symbols in a later article, for now we will use the built in DEBUG/RELEASE. One thing to remember the symbols have to be defined in a Boolean way. You cannot check numeric type values.
Before we show an example a quick explanation of #endif. As the name suggest it tells the preprocessor that this is the end of the conditional directive. Any directive with an #if has to be terminated with an #endif otherwise you will get a compile error.
Here is a simple example:
public class Program
{
#if DEBUG
public string WhichDatabase = "TestDb";
#endif
Noticed that we have set the symbol to DEBUG, this has significant meaning. The preprocessor will detect the #if, look at the symbol, in this case DEBUG is a reference to which build configuration is set.
If the build configuration is set to Debug at build/compile time this is what the output would look like: (As usual I am using Telerik’s JustDecompile.
public Program()
{
this.WhichDatabase = "TestDb";
As you can see the preprocessor detected that we were in the Debug configuration and added the code in the conditional directive. Not a very impressive example but what if we want to switch the database target based on which configuration we are in. Debug or Release mode.
This can be accomplished one of two ways. Just like a standard if condition we have access to #else.
#else works the same way as standard code. If the ‘if’ condition is false then the else condition is used. Continuing with the example at hand, we may want to assume if we are not in debug then we are in release. We can write up an example like below:
#if DEBUG
public string WhichServer = "TestDb";
#else
public string WhichServer = "LiveDb";
#endif
Lets set the build configuration to release and build. Below is output:
public Program()
{
this.WhichServer = "LiveDb";
As you can see the DEBUG check was false so the code block for the else was used.
There are many more coming, there are about 14 preprocessor directives in Visual Studio 2010/ .NET 4. At the end I will also cover the dangers and how you can get into trouble quickly.
As always please let me know if there is anything you would like to see an example of.