it-swarm.com.de

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

In den Lösungseigenschaften ist die Konfiguration für mein einziges Projekt auf "Freigabe" festgelegt.

Zu Beginn der Hauptroutine habe ich diesen Code und er zeigt "Mode = Debug". Ich habe auch 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, verschiedene Standardeinstellungen für Variablen basierend auf dem Debug- oder Release-Modus festzulegen.

384
NealWalters

Entfernen Sie den #define DEBUG in Ihrem Code. Setzen Sie Präprozessoren in der Build-Konfiguration für diesen spezifischen Build (DEBUG/_DEBUG sollte bereits in VS definiert sein).

Der Grund, warum "Mode = Debug" ausgegeben wird, liegt an Ihrem #define und überspringt dann das Elif.

Der richtige Weg zu überprüfen ist auch:

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

Nicht auf FREIGABE prüfen

649
psychotik

Standardmäßig definiert Visual Studio DEBUG, wenn das Projekt im Debug-Modus kompiliert wird, und definiert es nicht, wenn es im Release-Modus ist. RELEASE ist im Release-Modus standardmäßig nicht definiert. Benutze so etwas:

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

Wenn Sie etwas nur im Freigabemodus tun möchten:

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

Beachten Sie auch, dass Sie das [Conditional("DEBUG")] -Attribut für Methoden verwenden können, die void zurückgeben, damit sie nur ausgeführt werden, wenn ein bestimmtes Symbol definiert ist. Der Compiler würde alle Aufrufe dieser Methoden entfernen, wenn das Symbol nicht definiert ist:

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

void Test() {
    PrintLog();
}
273
Mehrdad Afshari

Ich bevorzuge es so zu überprüfen, anstatt nach #defines zu suchen:

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

Mit der Einschränkung, dass Sie natürlich etwas im Debug-Modus kompilieren und bereitstellen könnten, aber immer noch nicht den Debugger angehängt haben.

186
Joel Coehoorn

Ich bin kein großer Fan von #if-Dingen, vor allem, wenn Sie alles auf Ihre Codebasis verteilen, da es Probleme gibt, wenn Debug-Builds erfolgreich sind, Release-Builds jedoch fehlschlagen, wenn Sie nicht aufpassen.

Ich habe mir also Folgendes ausgedacht (inspiriert von # 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;
    }
}
50
Tod Thomson
_bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
_

Die Methode Debug.Assert hat das Bedingungsattribut DEBUG. Wenn es nicht definiert ist, sind der Aufruf und die Zuweisung _isDebug = true_ beseitigt :

Wenn das Symbol definiert ist, wird der Anruf eingeschlossen. Andernfalls wird der Aufruf (einschließlich der Auswertung der Parameter des Aufrufs) weggelassen.

Wenn DEBUG definiert ist, wird isDebug auf true gesetzt (und an _Debug.Assert_ übergeben, was in diesem Fall nichts bewirkt).

20
AlexD

Wenn Sie versuchen, die für den Build-Typ definierte Variable zu verwenden, sollten Sie die beiden Zeilen entfernen ...

#define DEBUG  
#define RELEASE 

... diese führen dazu, dass das # if (DEBUG) immer wahr ist.

Außerdem gibt es kein standardmäßiges Symbol für die bedingte Kompilierung für RELEASE. Wenn Sie einen Sprung zu den Projekteigenschaften definieren möchten, klicken Sie auf die Registerkarte Erstellen und fügen Sie dann RELEASE zur Registerkarte hinzu. Textfeld Bedingte Kompilierungssymbole unter der Überschrift Allgemein .

Die andere Möglichkeit wäre, dies zu tun ...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif
19
Matthew Whited

Entfernen Sie Ihre Definitionen oben

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

Leicht modifizierte (bastardisierte?) Version der Antwort von Tod Thomson als statische Funktion und nicht als separate Klasse (ich wollte sie in einer WebForm-Ansicht aufrufen können, die von einer bereits enthaltenen viewutils-Klasse abhängt).

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}
7
LocalPCGuy

Stellen Sie sicher, dass Sie die DEBUG-Konstante in den Project Build Properties definieren. Dies aktiviert den #if DEBUG. Ich sehe keine vordefinierte RELEASE-Konstante, daher könnte dies bedeuten, dass sich alles, was sich nicht in einem DEBUG-Block befindet, im RELEASE-Modus befindet.

Define DEBUG constant in Project Build Properties

4
gridtrak

NameSpace

using System.Resources;
using System.Diagnostics;

Methode

   private static bool IsDebug()
    {
        object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
        if ((customAttributes != null) && (customAttributes.Length == 1))
        {
            DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
            return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
        }
        return false;
    }
4
Ehsan Enaloo

Ein Tipp, der Ihnen viel Zeit spart - vergessen Sie nicht, dass es nicht ausreicht, wenn Sie in der Build-Konfiguration debug auswählen (im Menü vs2012/13 unter BUILD => CONFIGURATION MANAGER).

Sie müssen auf das PUBLISH Configuration als solches achten:

enter image description here

3
ilans

Ich musste über einen besseren Weg nachdenken. Mir wurde klar, dass # if-Blöcke effektiv Kommentare in anderen Konfigurationen sind (vorausgesetzt DEBUG oder RELEASE; aber mit jedem Symbol wahr).

public class Mytest
    {
        public DateTime DateAndTimeOfTransaction;
    }

    public void ProcessCommand(Mytest Command)
        {
            CheckMyCommandPreconditions(Command);
            // do more stuff with Command...
        }

        [Conditional("DEBUG")]
        private static void CheckMyCommandPreconditions(Mytest Command)
        {
            if (Command.DateAndTimeOfTransaction > DateTime.Now)
                throw new InvalidOperationException("DateTime expected to be in the past");
        }
0
user11773533

Da der Zweck dieser COMPILER-Direktiven darin besteht, den Compiler anzuweisen, KEINEN Code, Debug-Code, Betacode oder vielleicht Code einzuschließen, der von allen Endbenutzern benötigt wird, mit Ausnahme derjenigen, die von der Werbeabteilung angegeben werden, dh #Define AdDept, die Sie möchten in der Lage sein, sie je nach Ihren Anforderungen einzuschließen oder zu entfernen. Ohne dass Sie Ihren Quellcode ändern müssen, wenn beispielsweise ein Nicht-AdDept in das AdDept integriert wird. Dann muss nur noch die Direktive #AdDept auf der Eigenschaftsseite der Compileroptionen einer vorhandenen Programmversion eingefügt und eine Kompilierung durchgeführt werden und wa la! Der Code des zusammengeführten Programms wird lebendig.

Möglicherweise möchten Sie auch ein Deklarativ für einen neuen Prozess verwenden, der nicht zur Hauptsendezeit bereit ist oder der erst dann im Code aktiv sein kann, wenn er freigegeben wird.

Jedenfalls mache ich das so.

0
mrMagik3805

Entfernen Sie die Definitionen und prüfen Sie, ob sich die Bedingung im Debug-Modus befindet. Sie müssen nicht überprüfen, ob sich die Direktive im Freigabemodus befindet.

Etwas wie das:

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