У меня была эта идея сегодня утром, чтобы избежать вложенных блоков try, как показано ниже.
procedure DoSomething;
var
T1, T2, T3 : TTestObject;
begin
T1 := TTestObject.Create('One');
try
T2 := TTestObject.Create('Two');
try
T3 := TTestObject.Create('Three');
try
//A bunch of code;
finally
T3.Free;
end;
finally
T2.Free;
end;
finally
T1.Free;
end;
end;
Воспользовавшись автоматическим подсчетом ссылок на интерфейсы, я придумал
Type
IDoFinally = interface
procedure DoFree(O : TObject);
end;
TDoFinally = class(TInterfacedObject, IDoFinally)
private
FreeObjectList : TObjectList;
public
procedure DoFree(O : TObject);
constructor Create;
destructor Destroy; override;
end;
//...
procedure TDoFinally.DoFree(O : TObject);
begin
FreeObjectList.Add(O);
end;
constructor TDoFinally.Create;
begin
FreeObjectList := TObjectList.Create(True);
end;
destructor TDoFinally.Destroy;
begin
FreeObjectList.Free;
inherited;
end;
Итак, предыдущий блок кода становится
procedure DoSomething;
var
T1, T2, T3 : TTestObject;
DoFinally : IDoFinally;
begin
DoFinally := TDoFinally.Create;
T1 := TTestObject.Create('One');
DoFinally.DoFree(T1);
T2 := TTestObject.Create('Two');
DoFinally.DoFree(T2);
T3 := TTestObject.Create('Three');
DoFinally.DoFree(T3);
// A Bunch of code;
end;
Мой вопрос: это работает или я что-то пропустил?
Для меня это выглядит довольно круто и делает код немного легче читать с уменьшенным количеством вложенности. Он также может быть расширен для хранения списка анонимных методов для выполнения таких действий, как закрытие файлов, запросов и т.д.