What is the alternative to having code with conditional compilation in C#?
I have a class that has lots of code that is based on # ifdef .. After sometime my code is unr
IF the reason you are using conditional compilation can be easily refactored, you might consider using the Managed Extensibility Framework to load the code dynamically based on conditions at runtime.
An alternative is to use the ConditionalAttribute. The conditional attribute works in a similar way.
#define TRACE_ON
using System;
using System.Diagnostics;
public class Trace
{
[Conditional("TRACE_ON")]
public static void Msg(string msg)
{
Console.WriteLine(msg);
}
}
public class ProgramClass
{
static void Main()
{
Trace.Msg("Now in Main...");
Console.WriteLine("Done.");
}
}
One thing is to use the ConditionalAttribute:
[Conditional("DEBUG")]
public void Foo()
{
// Stuff
}
// This call will only be compiled into the code if the DEBUG symbol is defined
Foo();
It's still conditional compilation, but based on attributes rather than #ifdef
, which makes it generally simpler.
Another alternative is simply to use Boolean values at execution time, instead of doing it all at compile time. If you could give us more details of what you're trying to achieve and how you're using conditional compilation, that would be useful.
If it's a code-readability issue, you might consider using .Net's partial class qualifier and put the conditional code in separate files, so maybe you could have something like this...
foo.cs:
public partial class Foo
{
// Shared Behavior
}
foo.Debug.cs:
#if DEBUG
public partial class Foo
{
// debug Behavior
}
#endif
foo.bar.cs:
#define BAR
#if BAR
public partial class Foo
{
// special "BAR" Behavior
}
#endif
I'm not sure whether or not you can define your conditionals outside of the code file though, so doing something like this might reduce the flexibility of the conditional definitions (e.g. you might not be able to create a conditional branch against BAR in, say, the main file, and having to maintain multiple defined BARs could get ugly) as well as require a certain dilligence to go to the files to effectively enable/disable that bit of code.
So, using this approach might end up introducing more complications than it solves, but, depending on your code, maybe it could be helpful?
Expanding on Jon's answer, while there a number of limitations on using the ConditionalAttribute
, there is a significant advantage. When the condition is false, the calls to conditional method are omitted. For example, you can add 100's of calls to a logging system, say for debugging, that can be conditionally excluded from the production code. When they are excluded, there is no overhead associated with calling a method which does not need to be called. Using #ifdef, you would have to wrap every call to the logging system to conditionally exclude them.
Note this only works across assemblies, if the caller of the conditional method is re-compiled.
Using ConditionalAttribute would be a start. Otherwise, quite a bit of what folks often do with conditional compilation can usually be handled by inversion of control and/or judicious use of factories.