Introduction
Conditional compilation is the process of defining compiler directives that cause different parts of the code to be compiled, and others to be ignored. This technique can be used in a cross-platform development scenario to specify parts of the code that are compiled specific to a particular platform.[1]
Conditional compilation allows the compiler to skip some parts of the source code when compiling based on the conditional clauses. The #if ,#endif #elif and #else directives are used for conditional compilation. These directives add conditions to parts of a source file. With the use of these directives we can keep a single source file.
#if CONDITION
#else
#endif
It tells the compiler which code is to compile for the project.
The value of the condition determines which code block is included.
conditional-symbol:
Any identifier-or-keyword except true or false
conditional compilation directives should always be written as sets consisting of, in order, an #if
directive, zero or more #elif
directives, zero or one #else
directive, and an #endif
directive. Between these directive we have to write the conditional code.
Suppose if we have some code to be only compile if a certain condition is true we will define a condition with an ordinary if else statement. This is very helpful if we are working on a shared project.
Here is another C# example-
public int calculate(int input)
{
int result;
#if CONDITION
result= input + 10;
#else
result= input - 10;
#endif
return result;
}
The value of Condition will determine the functionality
CONDITION is set
result = input + 10;
CONDITION is not set
result = input - 10;
When to use Conditional Compilation
Using Conditional Compilation we can isolate platform-specific code so, we can use this anywhere according to our need. But if we are working on a large project it will make our code unmanageable. .Conditional compilation cannot be used in Portable Class Library because when it is compiled it generates only a single binary file .
Conditional Compilation in Windows Apps
In universal apps by using conditional compilation we can write code that can target different platforms i.e. Windows store and Windows Phone. We can choose which code is to compile for different project as both the project are compiled to different packages
This is the simplest way to define platform-specific code . For example, we could attempt to share our code base for Windows Phone and Windows Store apps, and change how your code behaves for each platform by surrounding platform-specific code with a condition that can be set depending on which app or platform we are compiling for. This will be more clear with the following example
Here is an example of conditional compilation in Universal windows Apps
First we are creating a C# universal app using a blank template. The solution is created using three projects a Windows Store app, a Windows Phone app and a Shared Project.
The first thing we notice in the solution is that both the windows store and windows phone projects have a separate start page which is the Main page. But we have to share this page so we will just drag one of them to the shared project and then we will delete the Main page from the other two projects. It wont create any problem as it is just a blank page.
Now we have a common shared Main page.
Before:
After:
In the Main page of shared project we are creating a simple UI, just a Button with an event handler and a TextBlock in which we want to display “Windows Store” if it is a Windows store app or “Windows Phone” if it is a Windows Phone app on a button click.
We will do this with conditional compilation in button click event handler
We will add conditions
#if WINDOWS_APP
#elif WINDOWS_PHONE_APP
We can see this condition by going to Properties->Build->Condition compilation symbols
Here in Windows properties the Conditional compilation symbol defined are NETFX_CORE and WINDOWS_APP and in Windows phone properties, NETFX_CORE and WINDOWS_PHONE_APP .
Windows 8 have a compiler directive set called NETFX_CORE. So, this is always set for a Windows 8 project and common in both Windows store and Windows phone.
Even we can add our compilation condition here, say "MY_COMPILATION_CONDITION" and can use this in our project but let’s go with the default one.
Our condition here is, if it is a windows phone application we want to display “Windows Phone” else we want to display “Windows store”. So in the event handler we will use Condition Compilation
We can see some code here is greyed out, this is just because intellisense is helping us with our conditional compilation. We can swap from windows to windows phone from the dropdown menu at the top. We can see here our platform is set to Windows , so the code related to other platform is greyed out. This is a very helpful feature as we can easily notice which code is going to compile specific to platforms.
Right click on the Windows project and select "Set as startup project" Now if we run the windows app by clicking on the button we get
And if we select Windows phone as startup project and run the project , Windows phone project will be running and we can see it is displaying Windows Phone instead of Windows Store.
An alternative way to share the view is
Conditional Compilation in XAML
If we use a TopAppBar in our shared project the application will run perfectly in windows store but we will get an exception in windows phone as top app bar is not available for windows phone.
There is a good way to manage differences between of XAML between Windows and Windows Phone is by using XAML Conditional Compilation. XCC is a preprocessor adding conditional compilation support to XAML files. We can enable XCC in your project by installing a tiny NuGet package.It supports Windows Universal apps and Xamarin Forms projects.
We will add this through nuget package manager. We will do this on solution level as we have to add this to both the projects. Whenever we reference any library or package from the shared project it needs to be added to both the projects.
Open the solution context menu and select "Manage NuGet Package for Solution". Search for xcc and install the XAML Conditional Compilation NuGet package in both projects.
After we have added the nuget package we have to declare it in the Main page where we want to use it.
We are adding the conditions for windows app and windows phone app
xmlns:win="condition:WINDOWS_APP"
xmlns:wp="condition:WINDOWS_PHONE_APP"
The xmlns:win and xmlns:wp attributes define the namespaces for conditional compiled XML elements and attributes. xmlns:win is used when we want the code to be compile for only windows store app and xmlns:wp is used when we want the code to be compiled for only Windows Phone app.
We have also to add it to be ignored else VS will give errors
mc:Ignorable="d win wp"
The mc:Ignorable attribute ensure the new xmlns prefixes are ignored by designers and compilers.
With the conditional compilation namespaces in place we can now enter the following XAML.Now we have to just add a prefix “win” or “wp” to our controls. Here in our example we want our TopAppBar to show only when it is a Windows Store application so we will add “win” to “Page.TopAppBar”.
I have also added “wp” to “Page.BottomAppBar”. Now it will only compile to windows Phone application.
If we run Windows App it will show only the Top App Bar
If we run Windows Phone App it will show only the Command Bar.
Intellisense does not work when we apply a custom prefix to an XML element. But we can enable Intellisense support by adding the mc:ProcessContent attribute.
mc:ProcessContent="win:* wp:*"
The mc:ProcessContent attribute enables Intellisense inside conditional regions.
Tips and Best practices
Don’t use #else if, #elseif or #elsif they won't work. You can use #elif instead.
XCC is in beta version so use it carefully.
If we use XCC to particular control, we won’t be able to see it at design time. My trick is to design it first and when I am satisfied with it I apply the Conditional Compilation to it.
Points of Interest
Universal Windows apps are time saving. We can build an app for Windows and Windows Phone at the same time, and share code, user controls, styles, strings, and other assets between the two projects in Visual Studio. This reduces the time and expense associated with building and maintaining an app for each type of device.
History
V1 of article.
References
https://msdn.microsoft.com/en-us/library/windows/apps/jj714084%28v=vs.105%29.aspx?f=255&MSPPError=-2147217396
https://github.com/firstfloorsoftware/xcc/wiki
https://xcc.codeplex.com/wikipage?title=Xamarin%20Forms