一个例子,我需要这样做来解决我正在开发的框架中的问题:
//Unit2 :
procedure A(aForm : TForm; AClassType: TFormClass);
begin
ShowMessage (AClassType(aForm).edtUser.text);
end;
...
//Unit1 :
Uses Unit2;
begin
form1 := TForm1.Create;
Try
A(form1, TForm1);
Finally
form1.Free;
End;
end;
编译器不接受此行:
AClassType (aform).edtUser.text
一种解决方案是使用:
Uses
UnitofTForm1;
The procedure (aform: TForm; AClassType: TForm1);
begin
ShowMessage (AClassType (aform).edtUser.text);
end;
但是我不能这样做,因为他们给出了循环引用,我需要在我的框架中进行一些解耦
有没有办法让类型转换作为参数传递给表单的类型,还是有其他方法可以做到这一点?
答案 0 :(得分:3)
你要求的是:
从公开要暴露您要访问的字段的公共基类派生各种Form类:
procedure A(aForm : TBaseForm);
begin
ShowMessage(aForm.edtUser.Text);
end;
type
TBaseForm = class(TForm)
edtUser: TEdit;
...
end;
TDerivedForm = class(TBaseForm)
...
end;
...
frm := TDerivedForm.Create;
try
A(frm);
finally
frm.Free;
end;
或使用泛型:
type
TBaseForm = class(TForm)
edtUser: TEdit;
...
end;
TMyClass = class
class procedure A<T: TBaseForm>(aForm : T);
end;
class procedure TMyClass.A<T>(aForm : T);
begin
ShowMessage(aForm.edtUser.Text);
end;
frm := TDerivedForm.Create;
try
A<TDerivedForm>(frm);
finally
frm.Free;
end;
如果无法使用公共基类,请改用接口:
type
IMyFormAccess = interface
function GetUserText: string;
end;
procedure A(aForm : IMyFormAccess);
begin
ShowMessage(aForm.GetUserText);
end;
type
TForm1 = class(TForm, IMyFormAccess)
...
function GetUserText: string;
...
end;
function TForm1.GetUserText: string;
begin
Result := edtUser.Text;
end;
...
frm := TForm1.Create;
try
A(frm as IMyFormAccess);
finally
frm.Free;
end;
或使用旧版RTTI(仅适用于已发布的属性):
uses
TypInfo;
procedure A(aForm : TForm);
var
Edt: TEdit;
begin
Edt := TEdit(GetObjectProp(aForm, 'edtUser', TEdit));
if Edt <> nil then
ShowMessage(Edt.Text);
end;
frm := TForm1.Create;
try
A(frm);
finally
frm.Free;
end;
或使用扩展RTTI(适用于所有字段和可见性):
uses
System.Rtti;
procedure A(aForm : TForm);
var
Ctx: TRttiContext;
Fld: TRttiField;
Value: TValue;
Edt: TEdit;
begin
Fld := Ctx.GetType(aForm.ClassType).GetField('edtUser');
if Fld <> nil then
begin
Value := Fld.GetValue(aForm);
if (not Value.IsEmpty) and Value.IsObject then
begin
Edt := Value.AsObject as TEdit;
ShowMessage(Edt.Text);
end;
end;
end;
frm := TForm1.Create;
try
A(frm);
finally
frm.Free;
end;