(anderer Thread)
-
FinallyExit (fände ich trotz allem besser als das try-finally-Gewurschtel
)
Ich glaube damit stehst du ziemlich allein. Warum sollte man das exakt selbe Feature doppelt implementieren? Bei den restlichen Punkten stimme ich dir aber weitestgehend zu.
Ich habe mal ein Testprojekt angehängt.
An den try-Blöcken stört mich die schlechte Debugbarkeit. Gerade habe ich einen Fehler gefunden, der in einer aufgerufenen Funktion auftrat. Durch den sch... try-Block war der schlechter lokalisierbar.
Ich mag die Dinger nicht und halte sie für wesentlich überschätzt.
Wenn man sie konsequent nutzen will, müsste man quasi jeden Befehl in einen try-Block kapseln.
Delphi-Quellcode:
A:=TA.Create;
B:=TB.Create;
try
...
finally
A.Free;
B.Free;
end;
Was aber, wenn schon TA.Create fehl schlägt???
Also müsste man dutzende try-Blöcke ineinander schachteln, um wirklich sicher zu sein?
Ich halte das für Unsinn.
In meinem Testprojekt kann man sehen, dass "end(normal)" nur in einem Fall aufgerufen wird.
Was ist aber bei 2 verschachtelten oder aufeinander folgenden try-Blöcken?
Ich halte ein Standardlabel "FinallyExit" für sehr sinnvoll, das einfach IMMER vor dem Verlassen einer Funktion/Prozedur angesprungen wird, egal was vorher auch immer passiert ist.
Sehr schwierig sollte das nicht lösbar sein, da ja weitestgehend nur die Exit-Sprungadresse geändert werden müsste.
PS: Das mit einem selbst definierten Label zu testen, wäre etwas umständlich, da man Exit(VALUE) so nicht (mit einer Anweisung) simulieren kann.
Delphi-Quellcode:
unit fTestFinallyExit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TFormTestFinallyExit =
class(TForm)
ButtonTest: TButton;
Memo: TMemo;
RadioGroupMode: TRadioGroup;
procedure RadioGroupModeClick(Sender: TObject);
private
{ Private-Deklarationen }
public
function Test:
String;
end;
var
FormTestFinallyExit: TFormTestFinallyExit;
implementation
{$R *.dfm}
procedure TFormTestFinallyExit.RadioGroupModeClick(Sender: TObject);
begin
Memo.Lines.Add('
-----' + RadioGroupMode.Items[RadioGroupMode.ItemIndex] + '
-----');
Memo.Lines.Add(Test);
Memo.Lines.Add('
');
end;
function TFormTestFinallyExit.Test:
String;
var
S:
String;
I: Integer;
procedure Add(SA:
String);
begin
S := S + SA + #13#10;
end;
begin
Result := '
nix';
S := '
';
I := 0;
Add('
begin');
if RadioGroupMode.ItemIndex = 1
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Exit;
end;
if RadioGroupMode.ItemIndex = 2
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Exit('
#');
end;
if RadioGroupMode.ItemIndex = 3
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Add(IntToStr(1
div I));
end;
try
Add('
try');
if RadioGroupMode.ItemIndex = 4
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Exit;
end;
if RadioGroupMode.ItemIndex = 5
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Exit('
#');
end;
if RadioGroupMode.ItemIndex = 6
then
begin
Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
Add(IntToStr(1
div I));
// springt in finally und dann Exit ohne Result-Zuweisung
end;
Add('
ok');
finally
Add('
finally');
Add('
end(finally)');
Result := S;
end;
Add('
end(normal)');
Result := S;
end;
end.