Was ist besser zu verwenden und warum bei einem großen Projekt:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
oder
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
c#
debugging
preprocessor
debug-symbols
Lucas B.
quelle
quelle
Antworten:
Es hängt wirklich davon ab, was Sie wollen:
#if DEBUG
: Der Code hier erreicht bei Veröffentlichung nicht einmal die IL.[Conditional("DEBUG")]
: Dieser Code erreicht die IL, Aufrufe der Methode werden jedoch weggelassen, es sei denn, DEBUG wird beim Kompilieren des Aufrufers festgelegt.Persönlich benutze ich beide je nach Situation:
Bedingt ("DEBUG") Beispiel: Ich verwende dies, damit ich später während der Veröffentlichung nicht zurückgehen und meinen Code bearbeiten muss, aber während des Debuggens möchte ich sicher sein, dass ich keine Tippfehler gemacht habe. Diese Funktion überprüft, ob ich einen Eigenschaftsnamen korrekt eingebe, wenn ich versuche, ihn in meinem INotifyPropertyChanged-Material zu verwenden.
Sie möchten wirklich keine Funktion mit erstellen, es
#if DEBUG
sei denn, Sie sind bereit, jeden Aufruf dieser Funktion mit demselben zu versehen#if DEBUG
:gegen:
#if DEBUG-Beispiel: Ich verwende dies, wenn ich versuche, verschiedene Bindungen für die WCF-Kommunikation einzurichten .
Im ersten Beispiel ist der gesamte Code vorhanden, wird jedoch nur ignoriert, wenn DEBUG aktiviert ist. Im zweiten Beispiel wird der const ENDPOINT auf "Localhost" oder "BasicHttpBinding" gesetzt, je nachdem, ob DEBUG gesetzt ist oder nicht.
Update: Ich aktualisiere diese Antwort, um einen wichtigen und kniffligen Punkt zu klären. Wenn Sie sich für die Verwendung von entscheiden
ConditionalAttribute
, beachten Sie, dass Aufrufe während der Kompilierung und nicht zur Laufzeit weggelassen werden . Das ist:MyLibrary.dll
Wenn die Bibliothek gegen den Freigabemodus kompiliert wird (dh kein DEBUG-Symbol), wird der Aufruf
B()
von innen für immerA()
weggelassen, selbst wenn ein Aufruf vonA()
enthalten ist, da DEBUG in der aufrufenden Assembly definiert ist.quelle
Nun, es ist erwähnenswert, dass sie überhaupt nicht dasselbe bedeuten.
Wenn das DEBUG-Symbol nicht definiert ist, wird im ersten Fall das
SetPrivateValue
selbst nicht aufgerufen ... während es im zweiten Fall existiert, aber bei allen Anrufern , die ohne das DEBUG-Symbol kompiliert wurden, werden diese Aufrufe weggelassen.Wenn der Code und alle seine Anrufer in der gleichen Anordnung ist dieser Unterschied weniger wichtig - aber es bedeutet , dass im ersten Fall , dass Sie auch brauchen , um
#if DEBUG
die um Aufruf als auch Code.Persönlich würde ich den zweiten Ansatz empfehlen - aber Sie müssen den Unterschied zwischen ihnen in Ihrem Kopf klar halten.
quelle
Ich bin mir sicher, dass viele mit mir nicht einverstanden sein werden, aber nachdem ich als Build-Typ ständig gehört habe, dass "Aber es funktioniert auf meiner Maschine!", Habe ich den Standpunkt vertreten, dass Sie es so gut wie nie verwenden sollten. Wenn Sie wirklich etwas zum Testen und Debuggen benötigen, finden Sie heraus, wie Sie diese Testbarkeit vom tatsächlichen Produktionscode trennen können.
Abstrahieren Sie die Szenarien mit Verspottung in Komponententests, erstellen Sie einmalige Versionen von Dingen für einmalige Szenarien, die Sie testen möchten, aber fügen Sie keine Debug-Tests in den Code für Binärdateien ein, die Sie testen und für die Produktionsversion schreiben. Diese Debug-Tests verbergen nur mögliche Fehler vor Entwicklern, sodass sie erst später im Prozess gefunden werden.
quelle
#if debug
ein ähnliches Konstrukt in Ihrem Code?#if DEBUG
damit andere nicht versehentlich Spam erhalten, während wir ein System testen, das E-Mails als Teil des Prozesses übertragen muss. Manchmal sind dies die richtigen Werkzeuge für den Job :)Dieser kann auch nützlich sein:
quelle
Debugger.IsAttached
zur Laufzeit auch in Release-Builds aufgerufen werden muss.Im ersten Beispiel ist
SetPrivateValue
der Build nicht vorhanden, wenn erDEBUG
nicht definiert ist. Im zweiten Beispiel sind Aufrufe vonSetPrivateValue
nicht im Build vorhanden, wenn erDEBUG
nicht definiert ist.Im ersten Beispiel müssen Sie auch alle Anrufe
SetPrivateValue
mit#if DEBUG
abschließen.Im zweiten Beispiel werden die Aufrufe von
SetPrivateValue
weggelassen, aber beachten Sie, dassSetPrivateValue
selbst noch kompiliert wird. Dies ist nützlich, wenn Sie eine Bibliothek erstellen, sodass eine Anwendung, die auf Ihre Bibliothek verweist, Ihre Funktion weiterhin verwenden kann (wenn die Bedingung erfüllt ist).Wenn Sie die Anrufe weglassen und den Platz des Angerufenen sparen möchten, können Sie eine Kombination der beiden Techniken verwenden:
quelle
#if DEBUG
umConditional("DEBUG")
nicht zu entfernen , die Anrufe zu dieser Funktion, es entfernt nur die Funktion von IL alltogether, so dass Sie immer noch Anrufe Funktion , die nicht (Kompilierungsfehler) nicht vorhanden ist .Nehmen wir an, Ihr Code hatte auch eine
#else
Anweisung, die eine Null-Stub-Funktion definierte und einen der Punkte von Jon Skeet ansprach. Es gibt einen zweiten wichtigen Unterschied zwischen den beiden.Angenommen, die Funktion
#if DEBUG
oderConditional
ist in einer DLL vorhanden, auf die Ihre ausführbare Hauptprojektdatei verweist. Mit dem#if
wird die Auswertung der Bedingung im Hinblick auf die Kompilierungseinstellungen der Bibliothek durchgeführt. Mit demConditional
Attribut wird die Auswertung der Bedingung hinsichtlich der Kompilierungseinstellungen des Aufrufers durchgeführt.quelle
Ich habe eine SOAP WebService-Erweiterung, um den Netzwerkverkehr mithilfe eines benutzerdefinierten Protokolls zu protokollieren
[TraceExtension]
. Ich verwende dies nur für Debug- Builds und lasse Release- Builds aus. Verwenden Sie das#if DEBUG
, um das[TraceExtension]
Attribut zu verpacken und es so aus Release- Builds zu entfernen .quelle
Normalerweise benötigen Sie es in Program.cs, wo Sie entscheiden möchten, ob Sie Debuggen mit Nicht-Debug-Code ausführen möchten, und dies auch meistens in Windows-Diensten. Also habe ich ein schreibgeschütztes Feld IsDebugMode erstellt und seinen Wert im statischen Konstruktor wie unten gezeigt festgelegt.
quelle