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.