views:

133

answers:

6

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 unreadable.

Looking for refactoring techniques to use for better readability and maintenance of code with many #if defs

+6  A: 

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.

Jon Skeet
+1  A: 

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.

Nicole Calinoiu
+1  A: 

Polymorphism.

Approach it the same way as you would any spaghetti code with lots of conditional branches on the same condition.

Abstract out the differences into a base class or interface.

Construct the concrete class depending on build (one #if). Pass the concrete object to your App, and then your app calls the methods defined on the interface.

Binary Worrier
+5  A: 

An alternative is to use the ContionalAttribute. 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.");
    }
}
TheCodeKing
+1  A: 

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?

Steven
A: 

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.

Mystere Man