避免嵌套的try …终于在Delphi中阻塞了

前端之家收集整理的这篇文章主要介绍了避免嵌套的try …终于在Delphi中阻塞了前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我今天早上有这个想法,避免嵌套的try finally如下
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,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;

我的问题是:这是工作还是让我忽略了一些东西?

对我来说,这看起来很酷,并且通过减少嵌套数量,使代码更容易阅读。它也可以扩展为存储匿名方法的列表来运行,以执行诸如关闭文件查询等的操作…

解决方法

是的,它有效。

也许唯一不同的是,原始代码的嵌套的try-finally块和使用引用计数对象来管理其他对象的生命周期的技术是如果有一个问题销毁任何对象会发生什么。如果任何对象被破坏时有异常,嵌套的try-finally块将确保任何剩余的对象仍然可以被释放。 TDoFinally中的TObjectList不这样做;如果列表中的任何项目不能被销毁,列表中的任何后续项目将被泄漏。

实际上,这不是一个真正的问题。没有析构函数应该抛出异常。如果是这样,没有任何方法可以从中恢复,所以没有任何事情会因为它而泄漏。您的程序应该暂时终止,因此整洁的清理程序并不重要。

顺便提一句,JCL已经提供了用于管理本地对象的生命周期的ISafeGuard和IMultiSafeGuard接口。例如,您可以重写代码,如下所示:

uses JclSysUtils;

procedure DoSomething;
var
  T1,T3: TTestObject;
  G: IMultiSafeGuard;
begin
  T1 := TTestObject(Guard(TTestObject.Create('One'),G));
  T2 := TTestObject(Guard(TTestObject.Create('Two'),G));
  T3 := TTestObject(Guard(TTestObject.Create('Three'),G));
  // A Bunch of code;
end;

该库也不解决析构函数中的异常。

猜你在找的Delphi相关文章