#if/#endif vs. ConditionalAttribut

Mit #if und #endif erstellter Code, der von der Build-Konfiguration anhängt, gilt in C# als schlechte Praxis. Es führt in den meisten Fällen zu schlecht les- und wartbarem Code. Außerdem können sich schnell Bugs einschleichen, die extrem schwer zu finden sind. Der folgende Code veranschaulicht, wie so etwas zum Beispiel passieren kann:

string msg = null;
#if DEBUG
msg = GetDiagnosticData();
#endif
Console.WriteLine(msg);

Wenn jetzt aber doch eine abhängige Konfiguration benötigt wird? Ein typisches Beispiel ist Trace. Das .NET Framework hat dafür das ConditionalAttribut. Das Attribut wird z.B. von den Trace- und Debug-Klassen im System.Diagnostics-Namensraum verwendet. Das Attribut muss auf einer Funktion vom Typ void angebracht sein:

static void Main(string[] args)
{
    WriteDebugString();
    Console.WriteLine("Done.");
    Console.ReadKey();
}
[Conditional("DEBUG")]
private static void WriteDebugString()
{
    Console.WriteLine("Conditional Text");
}

Der große Vorteil ist, dass seine solche Funktion an vielen Stellen verwendet werden kann. Ist das Compiler-Symbol nicht definiert, dann wird auch der Funktionsaufruf nicht kompiliert. Im Release-Build würde der obige Code im IL Code wie folgt aussehen:

static void Main(string[] args)
{
    Console.WriteLine("Done.");
    Console.ReadKey();
}

Es spart sich also die Performance-Kosten gegenüber einer Funktion, die intern mit #if/#end if bedingten Code hat, da ja bei jedem Aufruf sonst eine leere Funktion aufgreufen würde.

Vermeide konfigurationsabhängigen Code wann immer möglich.

Wenn wirklich nötig, dann verwende das ConditionalAttribut anstelle von #if/#endif.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s