C # if / then-Richtlinien für Debug-vs-Release
-
21-09-2019 - |
Frage
In Lösung Eigenschaften habe ich Konfiguration auf „Freigabe“ für meine erste und einzige Projekt.
Zu Beginn der Hauptroutine, habe ich diesen Code, und es zeigt „Mode = Debug“. Ich habe auch diese beiden Linien an der Spitze:
#define DEBUG
#define RELEASE
Testen Bin ich die richtige Variable?
#if (DEBUG)
Console.WriteLine("Mode=Debug");
#elif (RELEASE)
Console.WriteLine("Mode=Release");
#endif
Mein Ziel ist es verschiedene Voreinstellungen für Variablen auf Debug-vs Release-Modus basierend einzustellen.
Lösung
Entfernen Sie die #define DEBUG
in Ihrem Code. Set Preprozessoren in der Build-Konfiguration für diesen speziellen Build (DEBUG / _DEBUG sollte bereits in VS definiert werden).
Der Grund, es druckt "Mode = Debug" ist wegen Ihrer #define
und dann überspringt die elif
.
Auch der richtige Weg, zu überprüfen ist:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
nicht prüfen RELEASE
Andere Tipps
In der Standardeinstellung Visual Studio definiert DEBUG wenn Projekt im Debug-Modus kompiliert wird und es nicht definieren, wenn es in Release-Modus ist. RELEASE nicht im Release-Modus standardmäßig definiert. Verwenden Sie so etwas wie folgt aus:
#if DEBUG
// debug stuff goes here
#else
// release stuff goes here
#endif
Wenn Sie etwas tun wollen, nur im Release-Modus:
#if !DEBUG
// release...
#endif
Außerdem ist es erwähnenswert, dass Sie [Conditional("DEBUG")]
Attribut auf Methoden verwenden können, dass Rückkehr void
sie nur dann, wenn ein bestimmtes Symbol ausgeführt haben, definiert. Der Compiler würde alle Anrufe auf diese Methoden entfernen, wenn das Symbol nicht definiert ist:
[Conditional("DEBUG")]
void PrintLog() {
Console.WriteLine("Debug info");
}
void Test() {
PrintLog();
}
Ich ziehe es so Überprüfung für #defines vs suchen:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
Mit dem Vorbehalt natürlich, dass Sie in der Debug-Modus kompilieren und deploy etwas können aber noch nicht den Debugger angeschlossen.
Ich bin kein großer Fan von der # if stuff, vor allem wenn man sie alle um die Code-Basis zu verbreiten, da es Probleme geben wird, wo Debug Pass baut aber einen Release baut fehlschlagen, wenn Sie nicht vorsichtig sind.
Also hier ist, was ich habe kommen mit (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;
}
}
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
Die Methode Debug.Assert
hat bedingtes Attribut DEBUG
. Wenn es nicht definiert ist, wird der Anruf und die Zuordnung isDebug = true
ist eliminiert :
Wenn das Symbol definiert ist, wird der Anruf enthalten sind; andernfalls wird der Anruf (einschließlich Auswertung der Parameter des Anrufs) weggelassen.
Wenn DEBUG
definiert ist, isDebug
wird auf true
(und zu Debug.Assert
geführt, die nichts tut, in diesem Fall).
Wenn Sie versuchen, die Variable für den Buildtyp definiert zu verwenden, sollten Sie entfernen die zwei Zeilen ...
#define DEBUG
#define RELEASE
... das bewirkt, dass die # if (debug) immer wahr sein.
Auch gibt es keinen Standard Bedingte Compilierung Symbol für RELEASE . Wenn Sie einmal auf die Projekteigenschaften definieren möchten, klicken Sie auf die Schaltfläche Erstellen Registerkarte und fügen Sie dann RELEASE zu den Bedingte Compilierung Symbole Textfeld unter der Allgemein Überschrift.
Die andere Möglichkeit wäre, dies zu tun ...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
Entfernen Sie definiert an der Spitze
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
Leicht modifizierte (bastardized?) Version der Antwort von Tod Thomson als eine statische Funktion eher als eine separate Klasse (ich wollte in der Lage sein, es in einem Webformular aus einer viewutils Klasse viewbinding zu nennen bereits enthalten ich hatte).
public static bool isDebugging() {
bool debugging = false;
WellAreWe(ref debugging);
return debugging;
}
[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
debugging = true;
}
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;
}
Ein Tipp, dass Sie eine Menge Zeit sparen kann - vergessen Sie nicht, dass selbst wenn Sie debug
unter der Build-Konfiguration wählen (auf vs2012 / 13 Menü unter seinem BUILD => Konfigurations-Manager) - das ist nicht genug.
Sie müssen achten Sie auf die Configuration
VERÖFFENTLICHUNG, wie zum Beispiel:
Da der Zweck dieser Compiler-Direktiven sind dem Compiler mitzuteilen, keinen Code, Debug-Code, Beta-Code enthalten, oder vielleicht Code, der von allen Endbenutzer benötigt wird, mit Ausnahme derjenigen, die Werbeabteilung sagen, das heißt #Define AdDept Sie wollen in der Lage sein, übernehmen oder nach Ihren Bedürfnissen entfernen. Ohne den Quellcode, wenn zum Beispiel eine nicht AdDept geht in die AdDept zu ändern. Dann alles, was getan werden muss, ist die #AdDept Direktive in der Compiler-Optionen Eigenschaften Seite einer bestehenden Version des Programms auf und machen Sie einen Kompilierung und wa la! den Code des fusionierten Programm Federn am Leben!.
Sie mögen vielleicht auch einen deklarativen für ein neues Verfahren verwenden, die nicht bereit für die Prime Time ist oder dass kann, bis es an der Zeit im Code nicht aktiv sein, es zu veröffentlichen.
Wie auch immer, das ist so, wie ich es tun.
Ich habe über eine bessere Art und Weise zu denken. Es dämmerte mir, dass #if Blöcke sind Kommentare effektiv in anderen Konfigurationen (unter der Annahme DEBUG
oder RELEASE
, aber wahr mit jedem Symbol)
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");
}
die Definitionen entfernen und prüfen, ob die Voraussetzung für die Debug-Modus ist. Sie brauchen nicht zu prüfen, ob die Richtlinie über den Freigabemodus ist.
So etwas wie folgt aus:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif