IMyInterface = Interface(IInterfce)
procedure Go();
end;
MyClass = class(IMyInterface)
procedure Go();
end;
MyOtherClass = class
published
property name: string;
property data: MyClass;
end;
我正在使用RTTI设置“MyOtherClass”属性。对于字符串属性,它很容易,但我的问题是:
如何获取对“data”(MyClass)属性的引用,以便我可以调用Go()
方法?
我想做这样的事情(伪代码):
for i:= 0 to class.Properties.Count
if (propertyType is IMyInterface) then
IMyInterface(class.properties[i]).Go()
(如果这只是C#:()
PS:这是在delphi 7中(我知道,甚至更糟)
答案 0 :(得分:4)
如果字符串属性很简单,正如您所说,我假设您从GetStrProp
单元调用SetStrProp
和TypInfo
。 GetObjectProp
和SetObjectProp
可以轻松地使用类型属性。
if Supports(GetObjectProp(Obj, 'data'), IMyInterface, Intf) then
Intf.Go;
如果您真的不需要界面,并且知道data
属性的类型为TMyClass
,那么您可以更直接地进行访问:
(GetObjectProp(Obj, 'data') as TMyClass).Go;
这要求属性具有非空值。
如果您不知道所需属性的名称,则可以使用TypInfo
中的其他一些内容来搜索它。例如,这是一个函数,它将查找具有实现IMyInterface
的值的对象的所有已发布属性;它没有按特定顺序调用每个Go
。
procedure GoAllProperties(Other: TObject);
var
Properties: PPropList;
nProperties: Integer;
Info: PPropInfo;
Obj: TObject;
Intf: IMyInterface;
Unk: IUnknown;
begin
// Get a list of all the object's published properties
nProperties := GetPropList(Other.ClassInfo, Properties);
if nProperties > 0 then try
// Optional: sort the list
SortPropList(Properties, nProperties);
for i := 0 to Pred(nProperties) do begin
Info := Properties^[i];
// Skip write-only properties
if not Assigned(Info.GetProc) then
continue;
// Check what type the property holds
case Info.PropType^^.Kind of
tkClass: begin
// Get the object reference from the property
Obj := GetObjectProp(Other, Info);
// Check whether it implements IMyInterface
if Supports(Obj, IMyInterface, Intf) then
Intf.Go;
end;
tkInterface: begin
// Get the interface reference from the property
Unk := GetInterfaceProp(Obj, Info);
// Check whether it implements IMyInterface
if Supports(Unk, IMyInterface, Intf) then
Intf.Go;
end;
end;
end;
finally
FreeMem(Properties);
end;
end;
答案 1 :(得分:2)
您可以通过调用GetPropInfos(MyClass.ClassInfo)获取所有已发布属性的数组。这是一个PPropInfo指针数组。您可以通过调用GetTypeData从PPropInfo获取特定于类型的数据,该数据返回一个PTypeData。它指向的记录将包含您正在寻找关于类引用的信息。