Delphi.cz

Český portál Delphi

Delphi trik 6: generické anonymní metody

V novějších Delphi, nejméně XE3 - hlouběji jsem se nedíval, je v jednotce System.SysUtils definováno pár generických a zaroveň anonymních metod.

// Generic Anonymous method declarations
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;

Na co to je? Jedno z použítí je třeba opakovaná funkce, která se liší jen v jedné části, takže tu jednu část jen předáme jako anonymní metodu (v ukázce Browse, která má jako druhý parametr právě generickou funkci s dvěma parametry).

procedure TForm19.Browse(q: TDataset; pLine: TProc<Integer, TField>);
var
  x: Integer;
  oField: TField;
begin
  x := 1;
  oField := q.FieldByName('Name');
  while not q.Eof do
  begin
    pLine(x, oField);
    q.Next;
    inc(x);
  end;

end;

procedure TForm19.Button1Click(Sender: TObject);
begin
  Browse(FDQuery1,
    procedure (Line: Integer; Field:TField)
    begin
      memo1.Lines.Add(Format('%d: %s', [Line, Field.AsString]));
    end
    );

  Browse(FDQuery2,
    procedure (Line: Integer; Field:TField)
    begin
      log.Lines.Add(Format('%d: %s', [Line, Field.AsString]));
    end
    );
end;

No a když už jsem v tom, tak další využití anonymních metod je třeba při vývoji pro FMX, kdy hodně asynchronních dialogů používá stejný přístup, např.

TInputCloseDialogProc = reference to procedure(const AResult: TModalResult);


TDialogService = class
…
 class procedure ShowMessage(const AMessage: string; const ACloseDialogProc: TInputCloseDialogProc);
…

Datum: 2020-05-17 21:30:00 Tagy: generics

trik