rss
twitter
    Find out what I'm doing, Follow Me :)

Conditional Compilation in .Net

Here i would like to share the ways to do a conditional compilation in .Net.

Language: C#

We will discuss each of the following

  • Compiler Constants
  • Complier Constants Scope
  • Compiler constants declaration
  • Conditional Compilation for Methods
  • Conditional Compilation for Code Blocks
  • Conditional Compilation for Aspx/Ascx pages
  • Miscellaneous

Compiler Constants

Compiler Constants have two sources Reserved and custom.

Debug,Trace and Config are Reserved,Debug and Trace are boolean type and Config is string type

In C# you can declare a compiler constant by #define, /define , #undef and in

"Property Pages" each of these are explained later in the article.

Compiler Constants Scope

You can declare your compiler constants in

Property Pages dialog box

Public to all files in the project

Command line

Public to all files passed to the command-line compiler

#define,#undef statement in code

Private to the file in which it is declared

Web.config

Public to all files in the web project

Page level

Private to aspx/ascx page

Compiler Constants Declaration

In the Property Pages dialog box to access project properties

  1. Select the project and Right-click
  2. Then click on properties
  3. Select Build tab in properties dialog.
  4. In General section Enter your symbols in Conditional Compilation Symbols Textbox.
  5. You can enter Mutiple values by comma(,) seperated ex: SYMBOL1,SYMBOL2
  6. You can also check/uncheck DEBUG,TRACE const.

You can also refer to http://msdn.microsoft.com/en-us/library/aa288395(VS.71).aspx.

Command Line

CSC YourProj.cs /d:SYMBOL1;SYMBOL2

No space is required between the /d switch and the first constant.

Command-line declarations override declarations entered in the Property Pages dialog box.

Arguments set in Property Pages remain in effect for subsequent compilations.

When writing constants in the code itself, there are no strict rules as to their placement,

since their scope is the entire module in which they are declared.

Page Level

In page directive of aspx/ascx Page of a Web Project

<%@ Page Language="C#" CompilerOptions="/d:MYPAGESYMBOL" %>

Web.Config

In web.config of a web project

<system.codedom>

<compilers>

<compilerlanguage="c#;cs;csharp" extension=".cs" compilerOptions="/d:MYSYMBOL"

warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0,

Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

</compilers>

</system.codedom>

#define,#undef statement in code

A symbol can be defined either with the #define directive or the /define compiler option.

You can define a symbol, but you cannot assign a value to a symbol.

#define directive lets you to define a symbol.

Ex : #define MYSYMBOL

The #define directive must appear in the file before you use any instructions that are not also

directives.

there will be no ; after your symbol,

You cannot define multiple Symbols in a single #define directive.

if you want to use multiple Symbols then define for each symbol separately.

#undef lets you to undefine a symbol.T

Ex : #undef MYSYMBOL

The #undef directive must appear in the file before you use any statements that are not also

directives.

wondering how can undef is used.

Lets take a scenario where you have declared a symbol named PTOPERTYSYMBOL in the

property pages and you don’t want to apply that symbol in your code file ,then undefine at your

code file level with undef.

How to use

We have learn the scope and how to declare Compiler Constants.

Now i will explain how to use the compilation constants

so lets start with a simple console application class file

Listing:#1

using System;

class Program

{

static void Main(string[] args)

{

Console.WriteLine("Hello ");

Console.WriteLine("Bye");

Console.ReadLine();

}

}

Compilation constants in code bocks

now we will print “hello” to console if the compilation symbol is MYSYMBOL else “Bye”.

Listing:#2

#define MYSYMBOL

using System;

namespace ConditionalCompilation

{

class Program

{

static void Main(string[] args)

{

#if MYSYMBOL

Console.WriteLine("Hello ");

#else

Console.WriteLine("Bye");

#endif

Console.ReadLine();

}

}

}

OutPut:

Hello

if i change MYSMBOL from uppercase to lowercase like #if mysymbol

then my ouput is Bye beacuse they are case–sensitive

Now we will use multiple Compilation symbols

Listing:#3

#define MYSYMBOL

#define YOURSYMBOL

using System;

namespace ConditionalCompilation

{

class Program

{

static void Main(string[] args)

{

#if MYSYMBOL

Console.WriteLine("Hello ");

#endif

#if(YOURSYMBOL)

Console.WriteLine("Bye");

#endif

Console.ReadLine();

}

}

}

OutPut:

Hello

Bye

Now we will start undefining the symbols and we will avoid “Bye” output

Listing:#4

#define MYSYMBOL

#undef YOURSYMBOL

using System;

namespace ConditionalCompilation

{

class Program

{

static void Main(string[] args)

{

#if MYSYMBOL

Console.WriteLine("Hello ");

#elif(YOURSYMBOL == null)

Console.WriteLine("Bye");

#endif

Console.ReadLine();

}

}

}

OutPut:

Hello

Bye

Oops! we have a “Bye” output. if i had written the code as just #elif(YOURSYMBOL)

then our output would be just Hello.

if a symbol is not defined then the symbol value would be null/false.

ie. instead of #elif(YOURSYMBOL == null) you can have #elif(YOURSYMBOL != true) also.

constants may be undefined if not explicitly declared before being referenced by an if statement.

Compiler constants for Methods

The output of the following code is Hello

Listing:#5

using System;

namespace ConditionalCompilation

{

class Program

{

static void Main(string[] args)

{

#if MYSYMBOLINPROPERTYPAGES

Console.WriteLine("Hello ");

#endif

Console.ReadLine();

}

}

}

we have not defined any symbols in the code file still we have Hello output

this is because MYSYMBOLINPROPERTYPAGES is set in property pages and is applicable

to all the code files in the project

Now what if i don’t want my method to compile.

Listing:#6

#define MYSYMBOL

#undef YOURSYMBOL

using System;

using System.Diagnostics;

namespace ConditionalCompilation

{

class Program

{

[Conditional("MYSYMBOL")]

static void SayHi()

{

Console.WriteLine("Hello ");

}

[Conditional("YOURSYMBOL")]

static void SayBye()

{

Console.WriteLine("Bye");

}

static void Main(string[] args)

{

SayHi();

SayBye();

Console.ReadLine();

}

}

}

OutPut:

Hello

Conditional attribute:Indicates to compilers that a method call or attribute should be ignored

unless a specified conditional compilation symbol is defined.

for a method you can have multiple Conditional Attributes

Listing:#7

[Conditional("YOURSYMBOL")]

[Conditional("MYSYMBOL")]

static void SayHi()

{

Console.WriteLine("Hello ");

}

if any of the condition is true method will get compiled.

Conditional Compilation for Aspx/Ascx pages

Listing:#8

<%@ Page Language="C#" CompilerOptions="/d:MYSYMBOL" AutoEventWireup="true"

CodeBehind="Default.aspx.cs" Inherits="ConditionalCompilationWebApp._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title></title>

</head>

<body>

<form id="form1" runat="server">

<div>

<% #if YOURSYMBOL %>

<asp:Label ID="Label1" runat="server" Text="Label">BYE</asp:Label>

<% #elif(MYSYMBOL) %>

<asp:Label ID="Label2" runat="server" Text="Label">HELLO</asp:Label>

<% #endif %>

</div>

</form>

</body>

</html>

OutPut :

HELLO

here we defined only MYSYMBOL so Label with Hello content is executed.

with Multiple Symbols

Listing:#9

<%@ Page Language="C#" CompilerOptions="/d:MYSYMBOL;YOURSYMBOL" AutoEventWireup="true"

CodeBehind="Default.aspx.cs" Inherits="ConditionalCompilationWebApp._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title></title>

</head>

<body>

<form id="form1" runat="server">

<div>

<% #if YOURSYMBOL %>

<asp:Label ID="Label1" runat="server" Text="Label">BYE</asp:Label>

<% #endif %>

<% #if MYSYMBOL %>

<asp:Label ID="Label2" runat="server" Text="Label">HELLO</asp:Label>

<% #endif %>

</div>

</form>

</body>

</html>

OutPut:

BYE HELLO

Remember

<%#endif %> and <% #endif %> are different and the first one will not compile.

Miscellaneous

There are some other ways to define your constants

http://msdn.microsoft.com/en-us/library/ms228959.aspx

Thanks for reading

0 comments: