//事件过程指针
  TExceptionHandlerEvent = procedure (const AException: Exception; var Handled: Boolean) of object;
  //匿名方法
  TExceptionHandlerProc = reference to procedure (const AException: Exception; var Handled: Boolean);
 EAggregateException = class(Exception)
 {class↓ 内部类型TExceptionEnumerator 协助管理异常FInnerExceptions数组}
  public type
    TExceptionEnumerator = class //枚举器
    private
      FIndex: Integer; //FInnerExceptions数组的游标
      FException: EAggregateException; //拥有者
      function GetCurrent: Exception; inline;//获取游标指向的Exception对象
      //构建函数  参数是其拥有者
      constructor Create(const AException: EAggregateException);
    public
      //游标后移 
      function MoveNext: Boolean; inline;
      //游标指向的Exception对象
      property Current: Exception read GetCurrent;
    end;
  {class↑}
  private
    FInnerExceptions: TArray<Exception>;//内部存储异常数据数组
    function GetCount: Integer; inline;//返回异常个数
    function GetInnerException(Index: Integer): Exception; inline;//获取指定异常
    procedure ExtractExceptionsToList(const AList: TList<Exception>);//导出异常到AList
    //三种构建函数
    constructor Create(const AMessage: string; const AList: TList<Exception>); overload;
  public
    constructor Create(const AExceptionArray: array of Exception); overload;
    constructor Create(const AMessage: string; const AExceptionArray: array of Exception); overload;
    //解构函数
    destructor Destroy; override;
    //获取异常枚举器TExceptionEnumerator
    function GetEnumerator: TExceptionEnumerator; inline;
    // Handle函数 支持2中形式 匿名方法与事件指针
    procedure Handle(AExceptionHandlerEvent: TExceptionHandlerEvent); overload;
    procedure Handle(const AExceptionHandlerProc: TExceptionHandlerProc); overload;
    // FInnerExceptions所有异常信息字符串
    function ToString: string; override;
    property Count: Integer read GetCount;
    property InnerExceptions[Index: Integer]: Exception read GetInnerException; default;
  end;

//----------
implementation
//----------


procedure EAggregateException.Handle(AExceptionHandlerEvent: TExceptionHandlerEvent);
begin
  Handle(
    // 将事件指针转换成匿名函数,呼叫同名重载Handle函数
    procedure (const AException: Exception; var Handled: Boolean)
    begin
      AExceptionHandlerEvent(AException, Handled);
    end);
end;

// 参数  异常处理函数
// 如果异常完全处理完,则不触发异常信息。
//TExceptionHandlerProc = reference to procedure (const AException: Exception//注解:参数1:异常对象; var Handled: Boolean//注解:参数2:Out型参数 携带true返回则代表异常被成功处理);
procedure EAggregateException.Handle(const AExceptionHandlerProc: TExceptionHandlerProc);
var
  I: Integer;
  Handled: Boolean;
  List: TList<Exception>;
begin
  List := nil;
  try
    for I := 0 to Length(FInnerExceptions) - 1 do
    begin
      Handled := False;
      AExceptionHandlerProc(FInnerExceptions[I], Handled);
      if not Handled then
      begin
        if List = nil then
          List := TList<Exception>.Create;
        List.Add(FInnerExceptions[I]);
      end;
    end;
    if List <> nil then
    begin
      FInnerExceptions := nil;
      raise EAggregateException.Create(Message, List);
    end;
  finally
    List.Free;
  end;
end;

 

posted on 2016-06-04 23:22  心有猛虎·细嗅蔷薇  阅读(142)  评论(0)    收藏  举报