2009-09-08 48 views
3

嘿,所有,首先抱歉我的英语不好。 考虑以下(不实际的代码):基于RTTI信息的德尔福呼叫方法

IMyInterface = Interface(IInterfce) 
    procedure Go(); 
end; 

MyClass = class(IMyInterface) 
    procedure Go(); 
end; 

MyOtherClass = class 
published 
    property name: string; 
    property data: MyClass; 
end; 

我设置使用RTTI “MyOtherClass” 属性。对于字符串属性很容易,但我的问题是:

如何获得对“数据”(MyClass)属性的引用,以便我可以调用Go()方法?

我想要做这样的事情(伪代码):

for i:= 0 to class.Properties.Count 
    if (propertyType is IMyInterface) then 
    IMyInterface(class.properties[i]).Go() 

(如果只有这是C#:()

PS:这是在Delphi 7(我知道,即使更糟)

+1

德尔福2010年RTTI得到了很大的改进。有一个易于使用的单位称为rtti.pas。 换句话说切换到d2010,你会得到更少的痛苦。 – 2009-09-09 10:28:52

+0

我很想这么做,delphi中有许多很酷的新功能......但在这个项目中,我真的不能:/ - 但我会试着去得到2010年的试用版,只是为了看看它是如何工作的,说服我的老板:D – Leo 2009-09-09 12:58:22

+0

目前embarcadero正在德国巡回演出。 http://devtracks.de – 2009-09-09 13:29:17

回答

4

如果字符串属性很简单,就像您说的那样,那么我假设您从TypInfo单位调用GetStrPropSetStrProp。对于GetObjectPropSetObjectProp,类型属性可以同样容易。

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; 
+0

谢谢Rob,你的解决方案完美地解决了我的问题。这正是我所期待的 - 你应该得到RTTI-Hero徽章:) – Leo 2009-09-09 12:55:06

2

你可以得到的阵列中的所有出版致电GetPropInfos(MyClass.ClassInfo有产者),这是PPropInfo指针数组。而且你可以通过调用GetTypeData它在从PPropInfo特定类型的数据获取,它返回一个PTypeData。它指向的记录将包含你的信息e寻找关于类的参考。