![]() |
Exception Handling.
Ich habe mir gerade mal etwas Gedanken über Exceptions gemacht und wie man einen Code wasserdicht bekommt. Dies ist mein Ergebnis:
Delphi-Quellcode:
Jetzt frage ich mich, das ist doch der blanke Wahnsinn: Drei verschachtelte try-Blöcke!
procedure TForm1.Button1Click(Sender: TObject);
const TEXT = 'Dies ist ein Testtext.'; FILENAME = 'c:\test.txt'; var fs: TFileStream; s: String; begin s := TEXT; try {1} fs := TFileStream.Create(FILENAME, fmCreate); try {2} try {3} fs.WriteBuffer(Pointer(s)^, length(s)); except on E: EWriteError do ShowMessage(E.Message); end; finally FreeAndNil(fs); end; except on E: Exception do ShowMessage(E.Message); end; end; {1}: Um die Exception abzufangen, wenn die Methode Create von TFileStream fehlschlägt. Hier bringe ich zwar auch nur die Fehlermeldung, die die Exception selber bringen würde, aber eventuell will man ja noch was anders machen. {2}: Der obligatorische Ressourcenschutzblock. {3}: Um die Exception abzufangen, die WriteBuffer auslöst, wenn was schief geht beim Schreiben. Ist das denn normal oder übertreibe ich hier? Wie gesagt, meine ShowMessages steh da nur für alternativen Code. Das heißt will man anstatt den ShowMessages noch was anderes machen, dann müssen drei try-Blöcke sein - oder? |
Re: Exception Handling.
Delphi-Quellcode:
Dürfte das gleiche machen. Im Grunde sollte man pro Procedure mit einem try finally und einem try except auskommen können.
TEXT = 'Dies ist ein Testtext.';
FILENAME = 'c:\test.txt'; var fs: TFileStream; s: String; begin s := TEXT; try fs := TFileStream.Create(FILENAME, fmCreate); try fs.WriteBuffer(Pointer(s)^, length(s)); finally FreeAndNil(fs); end; except on E: EWriteError do ShowMessage(E.Message) else on E: Exception do ShowMessage(E.Message); end; end; Gruß Hagen |
Re: Exception Handling.
Hm. Gut. Sollte klappen.
Machen wir mal etwas weiter. Folgender Code:
Delphi-Quellcode:
Einfaches Beispiel, aber man sieht deutlich eine Funktion die True oder False zurück gibt hätte es auch getan. Wo liegt konkret der Vorteil von Exceptions? Oder anders gefragt, wann ist das werfen von Exceptions sinnvoll?
type
EInvalidPW = class(Exception); const PASSWORD = 'test'; procedure CheckPWD(Pwd: String); resourcestring rsInvalidPw = 'Ungültiges Passwort'; begin if Pwd <> PASSWORD then raise EInvalidPW.Create(rsInvalidPw); end; procedure TForm1.Button1Click(Sender: TObject); begin try CheckPWD('tset'); except on E: EInvalidPW do ShowMessage(E.Message); end; end; |
Re: Exception Handling.
Ganz genau das wollte ich mal meine Profs fragen. Der einzige Grund, den ich mir vorstellen kann, ist dass wenn eine Ausnahmesituation NICHT vom Programmierer behandelt wird, so stürzt der Rechner zumindest nicht ab, sondern es wird statt dessen eine unbehandelte Exception ausgelöst und angezeigt.
Wenn man aber sauber programmiert, dann kann man sich doch aber den ganzen (wie ich finde schwachsinnigen) Overhead sparen, gell!? OOP hin oder her... FEHLER müssen doch nicht unbedingt AUCH Objekte sein :roll: Finde Exceptions im wesentlichen genau so birnig wie das Geheimnisprinzip. Was soll ich erst einen Methodcall auslösen, wenn ich doch DIREKT und SCHNELL zugreifen könnte!? Das ist in meinen Augen völlig unnötige "Theorisierung" - zwanghaftes Anpassen an ein theroetisches Konzept. OOP ist SUPER! Keine Frage. Aber man muss es doch nicht auf Biegen und Brechen bis in alle Nieschen reinzwängen wollen... Danke Luckie! Bin ich doch nicht ganz so alleine mit meinem Gefühl :) gruss, dizzy |
Re: Exception Handling.
Nun ja, ich habe da eigentlich kein Gefühl, da ich weniger mit dem Bauch als mehr mit meinem Kopf - zu mindest versuche ich es - programmiere, deswegen frage ich hier. ;)
|
Re: Exception Handling.
Ähnliches passiert mir auch öfter ... irgendwann bin ich dann dazu übergegangen machen functions selbst zu schreiben, und keine 'Unhandled Exception' auszulösen, sondern die Fehlerbehandlung vor Ort durchzuführen.
Am beispiel von StrToInt:
Delphi-Quellcode:
Wenn die (ausgegebene) Variable E true ist, dann gab es keinen Fehler, wenn nicht, gab es einen. So hat man zwar ne if-Abfrage mehr, aber man könnte so mehrere konvertierungen zusammennehmen, und dann checken, ob es irgendwo nen fehler gab.
function StrToInt_(const S: string; out E : boolean) : integer;
var x : integer; begin Val(S, result, x); E := x <> 0; end; Diese Methode ist zwar umständlich, aber manchmal hilfreich. ciao, Philipp |
Re: Exception Handling.
Zitat:
oder du benutzt die eingebaute Funktion TryStrToInt von Delphi ;) mfG mirage228 |
Re: Exception Handling.
Ist die neu? Oder meinst du die, an die ich denke: "StrToIntDef".
|
Re: Exception Handling.
Zitat:
ja, anscheinend ist die neu in Delphi 6 (oder erst 7?).
Code:
Edit: Verflixte Tags :twisted:
function TryStrToInt(const S: string; out Value: Integer): Boolean;
Beschreibung TryStrToInt konvertiert den String S, der ein Integer repräsentiert (in dezimaler oder hexadezimaler Form), in eine Zahl und weist diese Value zu. Wenn S keine gültige Zahl enthält, gibt TryStrToInt false zurück; ansonsten true. mfG mirage228 |
Re: Exception Handling.
Könnten wir bitte beim Thema bleiben? Danke.
@Hagen: Was mir gerade bei deinem Code einfällt: Wenn das Schreiben eine Exception auslöst, wird dann auch das Objekt wieder freigegeben? Um das nämlich sicher zustellen, habe ich es nämlich so geschachtelt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz