C # - Was macht die Assert () -Methode? Ist es noch nützlich?


Antworten:


200

Nimmt bei einer Debug-Kompilierung Asserteine boolesche Bedingung als Parameter auf und zeigt den Fehlerdialog an, wenn die Bedingung falsch ist. Das Programm wird ohne Unterbrechung fortgesetzt, wenn die Bedingung erfüllt ist.

Wenn Sie in Release kompilieren, werden alle Debug.Assertautomatisch weggelassen.


12
Wie kann ich das gleiche Verhalten von Debug.Assert im Release-Modus erhalten?
Hamish Grubijan


8
@ HamishGrubijan Und warum solltest du Debug.Assertim Release-Modus?
Camilo Martin

25
IMO, das Weglassen von Behauptungen aus dem Release-Code ist wie das Durchführen von Rettungsbootübungen im angedockten Zustand und das Zurücklassen der Rettungsboote beim Segeln. :)
chrisd

113
Asserts sind kein Rettungsboot, sondern ein Eisberg-Erkennungssystem. Da der Benutzer das Schiff nicht steuert, sagt eine Bestätigung im Release-Code nur, dass sie zum Scheitern verurteilt sind. es lässt sie den Eisberg nicht meiden.
Stefan

97

Vom Code abgeschlossen

8 Defensive Programmierung

8.2 Behauptungen

Eine Zusicherung ist Code, der während der Entwicklung verwendet wird - normalerweise eine Routine oder ein Makro -, mit dem sich ein Programm während der Ausführung selbst überprüfen kann. Wenn eine Behauptung wahr ist, bedeutet dies, dass alles wie erwartet funktioniert. Wenn es falsch ist, bedeutet dies, dass ein unerwarteter Fehler im Code festgestellt wurde. Wenn das System beispielsweise davon ausgeht, dass eine Kundeninformationsdatei niemals mehr als 50.000 Datensätze enthält, enthält das Programm möglicherweise die Behauptung, dass die Anzahl der Datensätze kleiner oder gleich 50.000 ist. Solange die Anzahl der Datensätze kleiner oder gleich 50.000 ist, wird die Behauptung still sein. Wenn es jedoch auf mehr als 50.000 Datensätze stößt, wird laut "behauptet", dass ein Fehler im Programm vorliegt.

Behauptungen sind besonders nützlich in großen, komplizierten Programmen und in Programmen mit hoher Zuverlässigkeit. Sie ermöglichen es Programmierern, nicht übereinstimmende Schnittstellenannahmen, Fehler, die sich beim Ändern des Codes einschleichen, usw. schneller zu beseitigen.

Eine Behauptung benötigt normalerweise zwei Argumente: einen booleschen Ausdruck, der die Annahme beschreibt, die wahr sein soll, und eine Meldung, die angezeigt werden soll, wenn dies nicht der Fall ist.

(…)

Normalerweise möchten Sie nicht, dass Benutzer Bestätigungsnachrichten im Produktionscode sehen. Aussagen sind in erster Linie für die Entwicklung und Wartung bestimmt. Zusicherungen werden normalerweise zur Entwicklungszeit in den Code kompiliert und für die Produktion aus dem Code kompiliert. Während der Entwicklung werden durch Behauptungen widersprüchliche Annahmen, unerwartete Bedingungen, an Routinen übergebene schlechte Werte usw. gelöscht. Während der Produktion werden sie aus dem Code kompiliert, damit die Zusicherungen die Systemleistung nicht beeinträchtigen.


2
Das Buch Writing Solid Code enthält auch eine großartige Diskussion über die Verwendung von Assert. Sie sind ein großartiges Debugging-Tool!
Zooropa

39

Sie sollten es für Zeiten verwenden, in denen Sie nicht jede kleine Codezeile zum Überprüfen von Variablen auf einen Haltepunkt setzen müssen, aber in bestimmten Situationen eine Art Feedback erhalten möchten, zum Beispiel:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

Wenn ich eine ähnliche Codezeile wie oben hinzufüge, wird beim Ausführen meines Programms der folgende Fehler ausgegeben: "Fehler CS0103: Der Name 'Debug' ist im aktuellen Kontext nicht vorhanden". Benötige ich eine using-Anweisung, damit es funktioniert?
Josh Desmond

4
@ JoshDesmondSystem.Diagnostics
Sinjai

16

Assert bietet Ihnen auch eine weitere Gelegenheit, über die Designfähigkeiten der Benutzeroberfläche von Microsoft zu lachen. Ich meine: ein Dialog mit drei Schaltflächen Abbrechen, Wiederholen, Ignorieren und eine Erklärung, wie man sie in der Titelleiste interpretiert!


3
Abbrechen / Wiederholen / Ignorieren ist klassisch! Waren es Behauptungen, die Windows 3.1 dazu veranlassten, dies ständig anzuzeigen?
Devlord

Grundsätzlich liegt es daran, dass eine MessageBox verwendet wird, die, wie Sie sagen, auf Windows 3.1 zurückgeht und nur vordefinierte Schaltflächenbeschriftungen enthält. Sie können also verstehen, warum der Hack zustande gekommen ist, aber nicht, warum er 2008 noch da ist!
Joe

4
@Joe Dies sollte nur von Entwicklern und nicht von Endbenutzern gesehen werden. Daher ist das Aktualisieren wahrscheinlich ein Element mit extrem niedriger Priorität. Wenn es Sie stört, können Sie die Debug.Listeners- oder Trace.Listeners-Auflistungen ändern, um den Standardhandler durch einen zu ersetzen, der alles tut, was Sie wollen.
Dan spielt

5
Und nun ist es 2019 und das gleiche Dialogfeld / die gleichen Schaltflächen sind immer noch hier!
Bouke

10

Mit Assert können Sie eine Bedingung (post oder pre) bestätigen, die in Ihrem Code gilt. Auf diese Weise können Sie Ihre Absichten dokumentieren und sich vom Debugger in einem Dialogfeld informieren lassen, wenn Ihre Absicht nicht erfüllt wird.

Im Gegensatz zu einem Haltepunkt passt der Assert zu Ihrem Code und kann verwendet werden, um zusätzliche Details zu Ihrer Absicht hinzuzufügen.


10

Assert kann Ihnen dabei helfen, zwischen Test und Release ein separates Messaging-Verhalten festzulegen. Beispielsweise,

Debug.Assert(x > 2)

löst nur dann eine Unterbrechung aus, wenn Sie einen "Debug" -Build ausführen, keinen Release-Build. Es gibt ein vollständiges Beispiel für dieses Verhalten hier


10

Zunächst steht die Assert()Methode für Traceund DebugKlassen zur Verfügung.
Debug.Assert()wird nur im Debug-Modus ausgeführt.
Trace.Assert()wird im Debug- und Release-Modus ausgeführt.

Hier ist ein Beispiel:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Führen Sie diesen Code im Debug-Modus und dann im Release-Modus aus.

Geben Sie hier die Bildbeschreibung ein

Sie werden feststellen, dass im Debug-Modus Ihre Code- Debug.AssertAnweisung fehlschlägt. Sie erhalten ein Meldungsfeld mit dem aktuellen Stack-Trace der Anwendung. Dies geschieht nicht im Release-Modus, da die Trace.Assert()Bedingung erfüllt ist (i == 4).

WriteLine() Mit dieser Methode können Sie die Informationen einfach in der Visual Studio-Ausgabe protokollieren. Geben Sie hier die Bildbeschreibung ein


5

Behauptungen spielen eine wichtige Rolle in Design by Contract (DbC), das meines Wissens von Meyer, Bertand, eingeführt / gebilligt wurde. 1997. Objektorientierte Softwarekonstruktion.

Ein wichtiges Merkmal ist, dass sie keine Nebenwirkungen hervorrufen dürfen. Sie können beispielsweise eine Ausnahme behandeln oder mit einer if-Anweisung (defensive Programmierung) eine andere Vorgehensweise ergreifen.

Behauptungen werden verwendet, um die Vor- / Nachbedingungen des Vertrags, die Beziehung zwischen Kunde und Lieferant zu überprüfen - der Kunde muss sicherstellen, dass die Voraussetzungen des Lieferanten erfüllt sind, z. sendet £ 5 und der Lieferant muss sicherstellen, dass die Nachbedingungen erfüllt sind, z. liefert 12 Rosen. (Nur eine einfache Erklärung des Kunden / Lieferanten - kann weniger akzeptieren und mehr liefern, aber über Behauptungen). C # führt auch Trace.Assert () ein, das für den Release-Code verwendet werden kann.

Um die Frage mit Ja zu beantworten, sind sie immer noch nützlich, können aber die Komplexität + Lesbarkeit von Code und Zeit erhöhen + sind schwer zu warten. Sollen wir sie noch benutzen? Ja, werden wir sie alle benutzen? Wahrscheinlich nicht oder nicht in dem Maße, wie Meyer es beschreibt.

(Selbst der OU-Java-Kurs, in dem ich diese Technik gelernt habe, zeigte nur einfache Beispiele, und der Rest des Codes erzwang die DbC-Assertionsregeln für den größten Teil des Codes nicht, wurde jedoch zur Gewährleistung der Programmkorrektheit verwendet!)


3

Ich denke, Debug.Assert ist eine Möglichkeit, einen Vertrag darüber zu schließen, wie eine Methode aufgerufen werden soll, wobei der Schwerpunkt auf Einzelheiten zu den Werten eines Parameters liegt (anstatt nur auf dem Typ). Wenn Sie beispielsweise im zweiten Parameter keine Null senden sollen, fügen Sie den Assert um diesen Parameter hinzu, um den Verbraucher anzuweisen, dies nicht zu tun.

Es verhindert, dass jemand Ihren Code ohne Kopf verwendet. Es ermöglicht aber auch, dass dieser knochige Weg zur Produktion geht und nicht die böse Nachricht an einen Kunden weitergibt (vorausgesetzt, Sie erstellen einen Release-Build).


6
Es ist jedoch wichtig darauf hinzuweisen, dass ungültige Parameter für öffentliche Methoden Argumentausnahmen auslösen sollten. Nur private Methoden sollten Eingaben mit Zusicherungen validieren. Werte, die von außen kommen, sind immer verdächtig!
Jeffrey L Whitledge
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.