Delphi 如何使用类型为的类的泛型帮助器
我正在试图弄清楚如何泛化这个helper方法;因此,它将返回请求的相同类型:Delphi 如何使用类型为的类的泛型帮助器,delphi,generics,delphi-xe6,Delphi,Generics,Delphi Xe6,我正在试图弄清楚如何泛化这个helper方法;因此,它将返回请求的相同类型: type TScreenHelper = class helper for TScreen public function FindForm(DesiredFormClass: TFormClass): TForm; end; 现在,调用者必须将返回值强制转换为他们已经想要的类型: var frmReportReminderSetup: TfrmReportReminde
type
TScreenHelper = class helper for TScreen
public
function FindForm(DesiredFormClass: TFormClass): TForm;
end;
现在,调用者必须将返回值强制转换为他们已经想要的类型:
var
frmReportReminderSetup: TfrmReportReminderSetup;
begin
//frmReportReminderSetup := Screen.FindForm(TfrmReportReminderSetup); Doesn't compile
frmReportReminderSetup := TfrmReportReminderSetup(Screen.FindForm(TfrmReportReminderSetup));
非通用实现是:
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;
仿制药
我想要的是某种使用泛型的方法,以便函数返回它要求的类型
frmContoso := Screen.FindForm(TfrmContoso);
在伪代码中,我想要的签名类似于:
function FindForm(T: TFormClass): T;
当需要将其转换为实际的Delphi语法时,我认为您必须在尖括号中指定一个T引用:
function FindForm(<T>): T;
我能看出有什么不对劲。它不理解t是一个类(即,如果它是一个Integer
,那么将其设置为nil将是绝对错误的)
约束条件
因此,我需要以某种方式向编译器提示T
将是什么类型:
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;
示例非工作代码
程序项目2;
{$APPTYPE控制台}
{$R*.res}
使用
System.SysUtils、Vcl.Forms;
类型
TScreenHelperCore=类(ToObject)
公众的
类函数FindForm:T;
结束;
TfrmContoso=类(TForm)
公众的
结束;
{TScreenHelperCore}
类函数TScreenHelperCore.FindForm:T;
//\\\\[dcc32错误]项目2.dpr(23):E2029',',';'或应为“>”但找到“:”
变量
f:TForm;
i:整数;
开始
结果:=无;
对于i:=0到Screen.FormCount-1 do//Screen.Forms不支持枚举
开始
f:=屏幕表格[i];
如果(f)是T,那么
开始
结果:=f;
出口
结束;
结束;
结束;
变量
f:TfrmContoso;
开始
尝试
f:=TScreenHelperCore.FindForm;
如果f=nil,则
f:=TfrmContoso.Create(nil);
f、 ShowModal;
除了
关于E:Exception-do
Writeln(E.ClassName,“:”,E.Message);
结束;
结束。
您的约束是错误的。而不是
function FindForm<T: TFormClass>: T;
你确定这是正确的语法吗?我得到了E2029',',';'或“>”应为,但“:”在T:
的中间找到。另外,如果T
被限制为类型TForm
,那么我不需要在XE7中编译类型TForm
。我接受约束部分中的代码,并将TFormClass更改为TForm。并移除实现中的约束。无需重复。我已更新了问题,以包含一个完整的非功能性控制台测试应用程序。你能给我看一下你的代码吗,这样我们就可以比较一下为什么你的代码不能编译了?是的,你说在助手中不可能有泛型。所以我消除了无关的困惑。如果愿意,我可以从helper类TScreenHelper
包装对TScreenHelper核心的调用。我也可以删除这个问题,然后再问一次,除非删除对“helper”的引用可以严格关注“泛型”问题。我知道什么?!你需要找一个真正的专家。伊恩@XE6!?D5怎么了?;)我只看了3-4页就知道是谁写了这个问题:)@NGLN跟上时代。我们继续前进@LURD的确如此。我从我手机的第一页就知道了@我的雇主决定花3000美元买一个新版本。三个月后,错误百出的升级已经过时:(
Result := nil; E2010 Incompatible types: 'T' and 'Pointer'
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;
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.
function FindForm<T: TFormClass>: T;
function FindForm<T: TForm>: T;
{$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.