| 

.NET C# Java Javascript Exception

7
#include <assert.h>
int strlenChecked(char* s) {
assert(s != NULL);
return strlen(s);
}

Der Code oben ist ein Beispiel für die Benutzung von Assertions. Ich sehe da keine Vorteile gegenüber einer Exception. Wofür sind sie gut?
News:
20.10.2009
ermin 1,3k 2 7
ermin 1,3k 2 7
3 Antworten
7
Eine Assert-Anweisung ist einfach eine bedingte Anweisung, die wahr sein sollte, gefolgt von Text, der ausgegeben wird, wenn dies nicht zutrifft.

Asserts sind Conditonal-Brakepoints im Code. Sie helfen dem Programmierer dabei wärend der Entwicklung darauf zu achten, das alles seinen richtigen gang geht. Wird eine Assert-Anweisung ausgelößt, hat man einen Fehler in seiner Programmlogik. Nicht aber zwingend auch im Programm selbst. Nehmen wir ein Beispiel eine Funktion die 2 werte dividiert.

public function double dividiere(double dividend, double divisor){
Debug.Assert ( divisor != 0 , "Divisor ist 0!" );
if( divisor != 0 ) return dividend / devisor;
return 0;
}


Hier wird niemals eine Exeption geworfen, da die Division durch 0 behandelt wird. Jedoch möchte ich gern als Programmierer wissen, das eine Division durch 0 überhaupt "angefordert" wurde, da das garnicht passieren sollte. Da es nicht passieren sollte haben wir folgerichtig eine Fehler in unsere Programmlogik. Dafür nehme ich "Debug.Assert" was bewirkt, das der Debugger an dieser stelle anhällt, wenn der divisor 0 ist. Natürlich kann ich das auch mit Conditional-Brakepoints lösen jedoch sind die deutlich langsamer und in großen Projekten zu umständlich. Hin zu kommt das nicht in jeder Programmierumgebung Conditional-Brakepoints im Projekt-file gespeichert werden was Entwicklungen in Programmierteams erschweren würde, da jeder selbst die Brakepoints und ihren Bedingungen pflegen müßte. Als dritte alternative Lösung könnte man natürlich auch die Division duch 0 nicht behandeln und eine Exeption schmeißen. 1. ist dies jedoch nicht in jedem Fall gewünscht und zweitens kann man über eine Exeption nicht "drübersteigen". Über Asserts und Conditnal Brakepoints schon.

Mehr Details:

MSDN :: Assertionen in verwaltetem Code
Galileo Openbook C# :: Kapitel 33 Defensive Programmierung
20.10.2009
Floyd 14,6k 3 9
Floyd 14,6k 3 9
3
Wie in meinem Post diskutiert, können Assertions auch als Design-by-Contract aufgefasst werden und sind dann nicht nur Debugwerkzeuge sondern auch Sicherungs-Konzept. Der Unterschied ist für das Verständnis von Assertions wichtig.
LastFreeNickname 20.10.2009
4
Der große Wert von "Desgin by contract" zeigt sich, wenn mehrere Programmierer an einem Projekt arbeiten und jeder seine eigenen Klassen programmiert, die mit den Klassen der anderen Programmierer zusammenarbeiten müssen. Die Programmiersprache Eiffel beispielsweise verlangt assertions zwingend.
RomanB 20.10.2009
2
Scheinbar verhalten sich Java und .Net in diesem Punkt unterschiedlich. In Java bewirkt folgender Code in etwa das selbe (laut Wikipedia):

if(divisor == 0) thorw now DivisiorIsNullExceptin("Divisor ist 0!");
Debug.Assert ( divisor != 0 , "Divisor ist 0!" );
//Hab den Code C# Like geschrieben, da ich den JavaSyntax nicht genau kenne.

In .Net sind Assertions als Zusicherungen wärend der Entwicklung zu sehen, dies aber auch auf Kosten der Laufzeit und daher auch nicht in der Releaseversion enthalten (mit außer der Trace-Assertions wobei Microsoft hier keine exsesive Verwendung empfiehlt).

Floyd 20.10.2009
5
Meine Antwort bezieht sich jetzt nur auf Java. Dort wird selbst von offiziellen davon abgeraten, assert zu benutzen, weil es sich über eine Compiler-Flag deaktivieren lässt und somit zur Laufzeit keine Sicherungen mehr bestehen!

Das Thema dazu heißt Design-by-contract oder DBC. Du hast für jede Methode Pre- und Postconditions sovie Invarianten, die zu jeder Zeit der Ausführung gelten. Am besten liest du mal unter diesem Thema nach.

Ich empfehle die Benutzung einer Check-Klasse. Die kannst du selber schreiben oder eine offizielle nehmen. Wichtig ist nur, dass sie funktioniert und auch benutzt wird. Ein Aufruf für dein Beispiel nach Java portiert könnte z.B. so aussehen:

int stringLengthChecked(String s) {
Check.isNotNull(s);
return s.length();
}
20.10.2009
LastFreeNickname 316 1 7
2
Das man die Asserts mit einem Compiler-Flag deaktiveren kann ist ja auch gewollt und sinnvoll. Mann will im Releaseprodukt keine Asserts drin stehen haben, da Sie nicht zur Fehlerbehandlung gedacht sind sondern als Debug/Trace-Hilfe dienen.
Floyd 20.10.2009
3
Ja, aber genau das unterwandert DBC! Die gelten immer und auch bei der ausgelieferten Software. Ansonsten ist der Zustand der Software nicht mehr definiert.
LastFreeNickname 20.10.2009
2
Vestehe nicht was da das Problem ist. Asserts = Conditonal Brakepoints. Willst du die CB's auch in deinem Relaseprodukt haben? Ließ bitte mal meine Antwort. Vieleicht meinen wir beide ja auch was ganz anders.
Floyd 20.10.2009
3
Habe deinen Post gelesen und halte ihn in einem Punkt für falsch. Assertions (allgemein, nicht nur "assert") sollten nicht nur bei der Entwicklung gelten, da sie quasi Verträge mit dem Code darstellen, die selbstverständlich auch in der ausgelieferten Version gelten. Also nicht Conditional Breakpoints, sondern Verträge nach DBC! Wenn eine Assertion nicht gilt, ist die Software undefiniert und das muss entsprechend behandelt werden.
LastFreeNickname 20.10.2009
2
Zumindest in .Net mit dem Visual Studio sind standardmäßig im Releasebuild keine Asserts enthalten da Asserts die Build-Konstanten für Debug vorraussetzten und diese in Releasebuils nicht aktiviert sind. "Methoden der Debug-Klasse sind nicht in der Releaseversion des Programms enthalten. Sie erhöhen daher nicht den Umfang des Programms und beeinträchtigen nicht die Geschwindigkeit der Releaseversion." (Quelle MSDN) Alternative kann man ein Trace-Assert verwenden welches auch im Releasebuild enthalen sein kann.
Floyd 20.10.2009
2
Zumindest die MSDN und der Openbook-Artikel setzten Asserts nicht in Beziehung mit "Design by contract" und sehen darin somit auch keinen Vertrag. Ich zumindest sehe Asserts als Entwicklungswerkzeug und nicht als Programmierkonzept.
Floyd 20.10.2009
3
Ja diesen Unterschied hab ich auch festgestellt. Denke in Java (o.B.d.A.) sind Assertions eher als DBC und somit "hart" zu sehen, gerade weil das assert-Statement per Compiler-Flag deaktivierbar ist. Hab ja auch geschrieben, dass ich mich nur auf Java beziehe. ;-)
LastFreeNickname 20.10.2009
2
So wie ich das verstanden habe dienen asserts in Java nur dazu waehrend der Enwicklung eben kein Exception Handling betreiben zu muessen.

Genauso bei tests: die Ergebnisse werden ja von einem Entwickler interpretiert und dem reicht ein assert um zu sehen was schief laeuft (meistens ...)

Und was mir noch eingefallen ist: Soweit ich weiss wuerde die Runtime Environment mit default Einstellungen garnichts gegen ein "assert(5 != 5);" haben.
Man muss glaub ich einen parameter setzen um assertions zu aktivieren
20.10.2009
adalse0 161 1 4
adalse0 161 1 4

Stelle deine .net-Frage jetzt!