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
- Select the project and Right-click
- Then click on properties
- Select Build tab in properties dialog.
- In General section Enter your symbols in Conditional Compilation Symbols Textbox.
- You can enter Mutiple values by comma(,) seperated ex: SYMBOL1,SYMBOL2
- 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