How to use an auxiliary generic type

I am trying to figure out how to generalize this helper method; so it returns the same type that was set for:

type
    TScreenHelper = class helper for TScreen
    public
        function FindForm(DesiredFormClass: TFormClass): TForm;
    end;

At the moment, the caller must specify the return value that they already want:

var
   frmReportReminderSetup: TfrmReportReminderSetup;
begin
   //frmReportReminderSetup := Screen.FindForm(TfrmReportReminderSetup); Doesn't compile

   frmReportReminderSetup := TfrmReportReminderSetup(Screen.FindForm(TfrmReportReminderSetup));

Custom implementation:

function TScreenHelper.FindForm(DesiredFormClass: TFormClass): TForm;
var
    f: TForm;
    i: Integer;
begin
    Result := nil;

    for i := 0 to Screen.FormCount-1 do //Screen.Forms does not support enumeration
    begin
        f := Screen.Forms[i];

        if (f is DesiredFormClass) then
        begin
            Result := f;
            Exit;
        end;
    end;
end;

Generics

What I need is a way to use generics so that the function returns the type it requested.

frmContoso := Screen.FindForm(TfrmContoso);

In the pseudo code, the signature I want will look something like this:

function FindForm(T: TFormClass): T;

When the time comes to turn this into actual Delphi syntax, I think you should specify one of the T links in angle brackets:

function FindForm(<T>): T;

But I don't think it's allowed there ; I think this should be before the opening bracket:

function FindForm<T>: T;

Try

TScreenHelper = class helper for TScreen
public
    function FindFormOld(DesiredFormClass: TFormClass): TForm;
    function FindForm<T>: T;
end;

function TScreenHelper.FindForm<T>: T;
var
    f: TForm;
    i: Integer;
begin
    Result := nil;

    for i := 0 to Screen.FormCount-1 do //Screen.Forms does not support enumeration
    begin
        f := Screen.Forms[i];

        if (f is T) then
        begin
            Result := f as T;
            Exit;
        end;
    end;
end;

Except that you cannot compile:

Result := nil;  E2010 Incompatible types: 'T' and 'Pointer'

, . , T - ( , Integer? nil.)

- , T be:

TScreenHelper = class helper for TScreen
public
    function FindForm<T: TFormClass>: T;
end;

function TScreenHelper.FindForm<T: TFormClass>: T;
var
    f: TForm;
    i: Integer;
begin
    Result := nil;

    for i := 0 to Screen.FormCount-1 do //Screen.Forms does not support enumeration
    begin
        f := Screen.Forms[i];

        if (f is T) then
        begin
            Result := f as T;
            Exit;
        end;
    end;
end;

; . , :

frmContoso := Screen.FindForm<TfrmConsoto>();

; .

,

:

function FindForm<T: TFormClass>: T;

, TFormClass Delphi:

:

  • ,
  • "", "" ""

( )

, ; .

, . , 25 , Delphi.

TL;DR

:

function FindForm(DesiredFormClass: TFormClass): TForm;

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Vcl.Forms;

type
    TScreenHelperCore = class(TObject)
    public
        class function FindForm<T: TForm>: T;
    end;

    TfrmContoso = class(TForm)
    public

   end;

{ TScreenHelperCore }

class function TScreenHelperCore.FindForm<T: TForm>: T; 
//                                         \__[dcc32 Error] Project2.dpr(23): E2029 ',', ';' or '>' expected but ':' found
var
    f: TForm;
    i: Integer;
begin
    Result := nil;

    for i := 0 to Screen.FormCount-1 do //Screen.Forms does not support enumeration
    begin
        f := Screen.Forms[i];

        if (f is T) then
        begin
            Result := f;
            Exit;
        end;
    end;
end;

var
    f: TfrmContoso;

begin
  try
        f := TScreenHelperCore.FindForm<TfrmContoso>;
        if f = nil then
            f := TfrmContoso.Create(nil);

        f.ShowModal;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
+4
1

.

function FindForm<T: TFormClass>: T;

function FindForm<T: TForm>: T;

TMyForm, class of TMyForm.

, . , :

{$APPTYPE CONSOLE}
uses
  Vcl.Forms;

type
  TScreenHelper = class helper for TScreen
  public
    function FindForm<T: TForm>: T;
  end;

function TScreenHelper.FindForm<T>: T;
var
  f: TForm;
  i: Integer;
begin
  for i := 0 to Screen.FormCount - 1 do
  begin
    f := Screen.Forms[i];
    if (f is T) then
    begin
      Result := T(f);
      Exit;
    end;
  end;
  Result := nil;
end;

type
  TMyForm = class(TForm)
  end;

var
  Form: TMyForm;

begin
  Form := Screen.FindForm<TMyForm>;
end.
+5

All Articles