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 := 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.