Delphi中的匿名方法

Delphi中的匿名方法Anonymous Methods in Delphi

一、定义

顾名思义,匿名方法是没有名称的过程或函数。匿名方法将代码块视为实体,可以将其分配给变量或用作方法的参数。此外,匿名方法可以引用变量并将值绑定到定义该方法的上下文中的变量。可以使用简单的语法定义和使用匿名方法。它们类似于其他语言中定义的闭包的构造。As the name suggests, an anonymous method is a procedure or function that does not have a name associated with it. An anonymous method treats a block of code as an entity that can be assigned to a variable or used as a parameter to a method. In addition, an anonymous method can refer to variables and bind values to the variables in the context in which the method is defined. Anonymous methods can be defined and used with simple syntax. They are similar to the construct of closures defined in other languages.

二、案例

unit AsyncTask;

interface

uses
  System.SysUtils, System.Threading;

type
  TAsyncBackgroundTask<T> = reference to function: T;
  TAsyncSuccessCallback<T> = reference to procedure(
    const TaskResult:T );
  TAsyncErrorCallback = reference to procedure(
    const E: Exception );
  TAsyncDefaultErrorCallback = reference to procedure(
    const E: Exception;
    const ExptAddress: Pointer );

  Async = class sealed
  public
    class function Run<T>

    (
      Task: TAsyncBackgroundTask<T>;
      Success: TAsyncSuccessCallback<T>;
      Error: TAsyncErrorCallback = nil

    ) :ITask;
  end;

var
  DefaultTaskErrorHandler: TAsyncDefaultErrorCallback = nil;

implementation

uses
  System.Classes;

{ Async }

class function Async.Run<T>(
  Task: TAsyncBackgroundTask<T>;
  Success: TAsyncSuccessCallback<T>;
  Error: TAsyncErrorCallback ) :ITask;
var
  LRes: T;

begin
  Result := TTask.Run(
    procedure
    var
      Ex: Pointer;
      ExceptionAddress: Pointer;
    begin
      Ex := nil;
      try
        LRes := Task(); //:1.后台任务的方法:返回泛型T
        if Assigned(Success) then
          //:如果指定了参数Success的类型及其参照reference
        begin
          TThread.Queue(nil, //:Queue在主线程(UI线程)中运行
            procedure
            begin
              Success(LRes); //:2.队列化-后台任务的成功回调的函数:传入这个泛型T
            end);
        end;
      except
        Ex := AcquireExceptionObject;
          //:请求系统返回异常对象:system.AcquireExceptionObject
        ExceptionAddress := ExceptAddr;
          //:请求系统返回异常地址:system.ExceptAddr
        TThread.Queue(nil, //:Queue在主线程(UI线程)中运行
          procedure
          var
            LCurrException: Exception;
              //:系统异常类Exception实例变量
          begin
            LCurrException := Exception(Ex);
              //:系统异常类获取某个异常对象
            try
              if Assigned(Error) then
                Error(LCurrException)
                //:3.1.队列化-后台任务的异常回调的函数:传入这个异常LCurrException
              else
                DefaultTaskErrorHandler(
                  LCurrException,
                  ExceptionAddress );
                  //:3.2.队列化-后台任务的默认异常回调的函数:传入这个异常LCurrException及其地址ExceptionAddress
            finally
              FreeAndNil(LCurrException);
            end;
          end);
      end;
    end);
end;

initialization

  DefaultTaskErrorHandler :=
  procedure(
    const E: Exception;
    const ExceptionAddress: Pointer )
  begin
    ShowException(E, ExceptionAddress);
  end;

end.

三、匿名方法的定义

// Generic Anonymous method declarations  //System.SysUtils;
  //类:匿名方法的定义:
type
  TProc = reference to procedure;
  TProc<T> = reference to procedure (Arg1: T);
  TProc<T1,T2> = reference to procedure (Arg1: T1; Arg2: T2);
  TProc<T1,T2,T3> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3);
  TProc<T1,T2,T3,T4> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4);

  TFunc<TResult> = reference to function: TResult;
  TFunc<T,TResult> = reference to function (Arg1: T): TResult;
  TFunc<T1,T2,TResult> = reference to function (Arg1: T1; Arg2: T2): TResult;
  TFunc<T1,T2,T3,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult;
  TFunc<T1,T2,T3,T4,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult;

  TPredicate<T> = reference to function (Arg1: T): Boolean;  // Predicate : 匿名断言 (Assert (TPredicate<T>) )

匿名方法:匿名过程 匿名函数 匿名断言

发布了61 篇原创文章 · 获赞 6 · 访问量 5569

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/102675723