Assertionen in verwaltetem Code
Mithilfe einer Assertion oder einer Assert
-Anweisung wird eine Bedingung überprüft, die Sie als Argument der Assert
-Anweisung angeben. Wenn die Bedingung als "True" ausgewertet wird, erfolgt keine Aktion. Wenn die Bedingung auf "False" ausgewertet wird, schlägt die Assertion fehl. Wenn Sie das Programm mit einem Debugbuild erneut ausführen, wechselt es in den Unterbrechungsmodus.
Inhalt
Assertionen im System.Diagnostics-Namespace
Nebeneffekte der Debug.Assert-Methode
Anforderungen für Ablaufverfolgung und Debug
Anpassen des Assert-Verhaltens
Festlegen von Assertionen in Konfigurationsdateien
Assertionen im System.Diagnostics-Namespace
In Visual Basic und Visual C# können Sie die Assert
-Methode von Debug oder Trace verwenden, die sich im System.Diagnostics-Namespace befinden. Debug-Klassenmethoden sind in einer Releaseversion des Programms nicht enthalten, daher vergrößern sie weder den Releasecode noch reduzieren sie dessen Geschwindigkeit.
C++ unterstützt nicht die Debug-Klassenmethoden. Sie können dieselbe Wirkung durch Verwenden der Trace-Klasse mit bedingter Kompilierung erzielen, z.B. #ifdef DEBUG
... #endif
.
Die Debug.Assert-Methode
Sie können die System.Diagnostics.Debug.Assert-Methode beliebig verwenden, um Bedingungen zu überprüfen, die bei fehlerfreiem Code "True" ergeben sollten. Angenommen, Sie haben eine Funktion zum Dividieren von ganzen Zahlen geschrieben. Gemäß den Regeln der Mathematik kann der Divisor niemals 0 sein. Sie könnten diese Bedingung mithilfe einer Assertion testen:
int IntegerDivide ( int dividend , int divisor )
{
Debug.Assert ( divisor != 0 );
return ( dividend / divisor );
}
Wenn Sie diesen Code im Debugger ausführen, wird die Assertionsanweisung ausgewertet. In der Releaseversion findet der Vergleich jedoch nicht statt, sodass kein Mehraufwand entsteht.
Im Folgenden ist ein weiteres Beispiel angegeben. Sie verfügen über eine Klasse, mit der ein Girokonto wie folgt implementiert wird:
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Bevor Sie Geld von diesem Konto abheben, müssen Sie sicherstellen, dass das Konto genügend Deckung für den abzuhebenden Betrag aufweist. Sie können eine Assertion schreiben, um den Saldo zu überprüfen:
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Bedenken Sie, dass Aufrufe der System.Diagnostics.Debug.Assert-Methode nicht mehr verfügbar sind, wenn Sie eine Releaseversion des Codes erstellen. Dies bedeutet, dass der Aufruf zum Überprüfen des Kontosaldos in der Releaseversion nicht mehr vorhanden ist. Um dieses Problem zu beheben, ersetzen Sie System.Diagnostics.Debug.Assert durch System.Diagnostics.Trace.Assert, denn diese Methode ist in der Releaseversion weiterhin vorhanden:
Aufrufe von System.Diagnostics.Trace.Assert verursachen jedoch im Gegensatz zu Aufrufen von System.Diagnostics.Debug.Assert in der Releaseversion einen Mehraufwand.
Nebeneffekte der Debug.Assert-Methode
Stellen Sie bei Verwendung der System.Diagnostics.Debug.Assert-Methode sicher, dass die Programmergebnisse nicht vom Code innerhalb der Assert
-Methode beeinflusst werden, wenn Assert
entfernt wurde. Andernfalls kann dies zu einem Fehler führen, der lediglich in der Releaseversion des Programms auftritt. Auch bei Assertionen, die Funktions- oder Prozeduraufrufe enthalten, sollte besonders sorgfältig vorgegangen werden, wie im folgenden Beispiel:
Diese Verwendung der System.Diagnostics.Debug.Assert-Methode mag auf den ersten Blick sicher erscheinen. Was geschieht jedoch, wenn die Funktion "meas" bei jedem Aufruf einen Zähler aktualisiert? Bei der Erstellung der Releaseversion wird dieser Aufruf der Funktion „meas“ entfernt, sodass der Zähler nicht mehr aktualisiert wird. Dies ist ein Beispiel für eine Funktion mit einem Nebeneffekt. Durch das Entfernen eines Funktionsaufrufs, der Nebeneffekte hat, kann ein Fehler verursacht werden, der ausschließlich in der Releaseversion auftritt. Um derartige Probleme zu vermeiden, sollten Sie keine Funktionsaufrufe in eine System.Diagnostics.Debug.Assert-Anweisung einfügen. Verwenden Sie stattdessen eine temporäre Variable:
Auch wenn Sie die System.Diagnostics.Trace.Assert-Methode verwenden, möchten Sie möglicherweise Funktionsaufrufe innerhalb einer Assert
-Anweisung vermeiden. Solche Aufrufe sollten kein Risiko darstellen, da System.Diagnostics.Trace.Assert-Anweisungen nicht aus einem Releasebuild entfernt werden. Wenn Sie es sich jedoch zur Gewohnheit machen, solche Konstrukte zu vermeiden, können Sie Fehlern bei Verwendung der System.Diagnostics.Debug.Assert-Methode vorbeugen.
Voraussetzungen für Ablaufverfolgung und Debug
Wenn Sie das Projekt mithilfe der Visual Studio-Assistenten erstellen, wird das TRACE-Symbol sowohl in der Release- als auch in der Debugkonfiguration automatisch definiert. Das DEBUG-Symbol ist standardmäßig nur im Debugbuild definiert.
Andernfalls funktionieren die Trace-Methoden nur dann, wenn im Programm am Anfang der Quelldatei Folgendes steht:
#Const TRACE = True
in Visual Basic#define TRACE
in Visual C# und C++Oder das Programm muss mit der TRACE-Option erstellt werden:
/d:TRACE=True
in Visual Basic/d:TRACE
in Visual C# und C++Wenn Debug-Methoden in einem C#- oder Visual Basic-Releasebuild verwendet werden sollen, müssen Sie das DEBUG-Symbol in der Releasekonfiguration definieren.
C++ unterstützt nicht die Debug-Klassenmethoden. Sie können dieselbe Wirkung durch Verwenden der Trace-Klasse mit bedingter Kompilierung erzielen, z.B.
#ifdef DEBUG
...#endif
. Diese Symbole können im Dialogfeld für die <Projekt> Eigenschaftenseiten definiert werden. Weitere Informationen finden Sie unter Ändern von Projekteinstellungen für eine Visual Basic-Debugkonfiguration oder unter Ändern von Projekteinstellungen für eine C- oder C++-Debugkonfiguration.
Assert-Argumente
Die System.Diagnostics.Trace.Assert- und System.Diagnostics.Debug.Assert-Methoden nehmen bis zu drei Argumente an. Das erste Argument, das obligatorisch ist, bezieht sich auf die zu überprüfende Bedingung. Bei einem Aufruf der System.Diagnostics.Trace.Assert(Boolean)- oder System.Diagnostics.Debug.Assert(Boolean)-Methode mit nur einem Argument wird die Bedingung von der Assert
-Methode überprüft. Wenn das Ergebnis „False“ lautet, wird der Inhalt der Aufrufliste im Ausgabefenster angezeigt. Im folgenden Beispiel werden die System.Diagnostics.Trace.Assert(Boolean)- und System.Diagnostics.Debug.Assert(Boolean)-Methoden veranschaulicht:
Beim zweiten und dritten Argument (sofern vorhanden) muss es sich um Zeichenfolgen handeln. Wenn Sie die System.Diagnostics.Trace.Assert- oder System.Diagnostics.Debug.Assert-Methode mit zwei oder drei Argumenten aufrufen, ist das erste Argument eine Bedingung. Die Methode überprüft die Bedingung und gibt die als zweites und drittes Argument übergebenen Zeichenfolgen zurück, wenn das Ergebnis "False" lautet. Im folgenden Beispiel wird die Verwendung der System.Diagnostics.Debug.Assert(Boolean, String)- und System.Diagnostics.Trace.Assert(Boolean, String)-Methoden mit zwei Argumenten veranschaulicht:
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );
Im folgenden Beispiel wird die Verwendung der System.Diagnostics.Debug.Assert(Boolean, String, String)- und System.Diagnostics.Trace.Assert(Boolean, String, String)-Methoden mit drei Argumenten veranschaulicht:
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );
Anpassen des Assert-Verhaltens
Wenn Sie die Anwendung im Benutzeroberflächenmodus ausführen, wird durch die Assert
-Methode das Dialogfeld Assertionsfehler angezeigt, falls die Bedingung nicht erfüllt wird. Die Aktionen, die bei einem Assertionsfehler auszuführen sind, werden von der Listeners-Eigenschaft oder der Listeners-Eigenschaft gesteuert.
Das Ausgabeverhalten kann wie folgt angepasst werden: durch Hinzufügen eines TraceListener-Objekts zur Listeners
-Auflistung, durch Entfernen eines TraceListener-Objekts aus der Listeners
-Auflistung oder durch Überschreiben der System.Diagnostics.TraceListener.Fail-Methode eines vorhandenen TraceListener
-Objekts, um sein Verhalten zu ändern.
Sie können beispielsweise die System.Diagnostics.TraceListener.Fail-Methode überschreiben, um die Ausgabe in ein Ereignisprotokoll zu schreiben, anstatt das Dialogfeld Assertionsfehler anzuzeigen.
Damit die Ausgabe auf diese Weise angepasst werden kann, muss das Programm über einen Listener verfügen, der von TraceListener erbt und dessen System.Diagnostics.TraceListener.Fail-Methode überschrieben wird.
Weitere Informationen finden Sie unter Ablaufverfolgungslistener.
Festlegen von Assertionen in Konfigurationsdateien
Sie können Assertionen sowohl in der Programmkonfigurationsdatei als auch im Code festlegen. Weitere Informationen finden Sie unter System.Diagnostics.Trace.Assert oder System.Diagnostics.Debug.Assert.