547 Stimmen

C# if/then-Anweisungen für Debug vs. Release

In den Lösungseigenschaften habe ich die Konfiguration für mein einziges Projekt auf "Release" gesetzt.

Am Anfang der Hauptroutine habe ich diesen Code, und es wird "Mode=Debug" angezeigt. Außerdem habe ich diese beiden Zeilen ganz oben:

#define DEBUG 
#define RELEASE

Teste ich die richtige Variable?

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

Mein Ziel ist es, unterschiedliche Standardwerte für Variablen auf der Grundlage von Debug vs Release-Modus zu setzen.

14 Stimmen

Sie definieren beides, Debug und Release.

897voto

psychotik Punkte 36639

DEBUG / _DEBUG sollte bereits in VS definiert sein.

Entfernen Sie die #define DEBUG in Ihrem Code. Setzen Sie die Präprozessoren in der Build-Konfiguration für diesen speziellen Build.

Der Grund für die Ausgabe von "Mode=Debug" liegt in Ihrer #define und überspringt dann die elif .

Die richtige Art der Überprüfung ist:

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

Prüfen Sie nicht auf RELEASE .

86 Stimmen

Ich wollte noch hinzufügen, dass man dies tun kann, wenn man nur auf RELEASE prüfen möchte: #if !DEBUG

5 Stimmen

Warum #if und nicht #ifdef ?

27 Stimmen

@BobStein-VisiBone Denken Sie daran, dass wir hier über C# sprechen, nicht über C. #ifdef ist spezifisch für den Präprozessor von C/C++, C# schreibt die Verwendung von #if .

362voto

mmx Punkte 400975

Standardmäßig definiert Visual Studio DEBUG, wenn das Projekt im Debug-Modus kompiliert wurde, und definiert es nicht, wenn es sich im Release-Modus befindet. RELEASE ist im Release-Modus standardmäßig nicht definiert. Verwenden Sie etwas wie dieses:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif

Wenn Sie etwas nur im Freigabemodus tun wollen:

#if !DEBUG
  // release...
#endif

Außerdem ist es erwähnenswert, dass Sie mit [Conditional("DEBUG")] Attribut bei Methoden, die Folgendes zurückgeben void damit sie nur ausgeführt werden, wenn ein bestimmtes Symbol definiert ist. Der Compiler würde alle Aufrufe zu diesen Methoden entfernen, wenn das Symbol nicht definiert ist:

[Conditional("DEBUG")]
void PrintLog() {
    Console.WriteLine("Debug info");
}

void Test() {
    PrintLog();
}

11 Stimmen

Tolle Antwort, vielen Dank.

286voto

Joel Coehoorn Punkte 377088

Ich bevorzuge diese Art der Überprüfung gegenüber der Suche nach #define Richtlinien:

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

Mit dem Vorbehalt, dass Sie natürlich etwas im Debug-Modus kompilieren und bereitstellen können, ohne dass der Debugger angeschlossen ist.

3 Stimmen

Ich danke Ihnen! Ich weiß noch nicht einmal, was "#defines" sind, also ist dies eine großartige Lösung!

0 Stimmen

Und in meinem Fall ist das genau das, was ich will. Ich möchte eigentlich wissen, ob ich einen Debugger angeschlossen habe, weil ich weiß, dass ich einige Codes habe, die ich nicht ausführen möchte, wenn ich einen Debugger angeschlossen habe. Das ist großartig!

1 Stimmen

Wenn Sie persönlich gerne #IF DEBUG beim Debuggen von Code, der nicht dauern sollte. Für die Produktion Code stimme ich mit der Verwendung der oben genannten.

67voto

Tod Thomson Punkte 4653

Ich bin kein großer Fan des #if-Zeugs, vor allem, wenn man es über die gesamte Codebasis verteilt, da es zu Problemen führt, bei denen Debug-Builds funktionieren, Release-Builds aber fehlschlagen, wenn man nicht vorsichtig ist.

Also habe ich mir folgendes ausgedacht (inspiriert durch #ifdef in C# ):

public interface IDebuggingService
{
    bool RunningInDebugMode();
}

public class DebuggingService : IDebuggingService
{
    private bool debugging;

    public bool RunningInDebugMode()
    {
        //#if DEBUG
        //return true;
        //#else
        //return false;
        //#endif
        WellAreWe();
        return debugging;
    }

    [Conditional("DEBUG")]
    private void WellAreWe()
    {
        debugging = true;
    }
}

3 Stimmen

Hey, das ist ziemlich kreativ. Ich mag Ihre Verwendung des Attributs, um die Eigenschaft zu setzen.

6 Stimmen

Dies hat den Vorteil, dass Sie nicht von Refactoring-Fehlern in Resharper betroffen sind, die Ihren Code auf der Grundlage der aktuellen bedingten Einstellungen durcheinander bringen können.

3 Stimmen

Ich mag dies, aber ich frage mich, warum nicht eine Singleton-Implementierung für diese anstelle eines Dienstes erstellen. Es ist systemspezifisch und man muss sich nicht darum kümmern, es überall zu injizieren. (Können Sie sich ein Szenario vorstellen, in dem die Implementierung dieser Funktionalität anders sein würde?

34voto

AlexD Punkte 31181
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

Die Methode Debug.Assert hat ein bedingtes Attribut DEBUG . Wenn er nicht definiert ist, wird der Aufruf und die Zuordnung isDebug = true sind beseitigt :

Wenn das Symbol definiert ist, wird der Aufruf einbezogen; andernfalls wird der Aufruf (einschließlich der Auswertung der Parameter des Aufrufs) weggelassen.

Si DEBUG definiert ist, isDebug wird eingestellt auf true (und weitergegeben an Debug.Assert , die in diesem Fall nichts bewirkt).

0 Stimmen

Auch das ist eine ziemlich kreative Lösung :)

0 Stimmen

Sehr schön. Für eine Iterationsvariable, die sich zwischen Debug und Release ändern muss... var iterations = 10; Debug.Assert((iterations = Int32.MaxValue) > 0);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X