2009-09-08 6 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"속성을 설정하고있다. 문자열 속성에 대해서는 간단하지만 제 질문은

Go() 메서드를 호출 할 수 있도록 "데이터"(MyClass) 속성에 대한 참조를 얻을 수 있습니까?

나는이 (의사 코드) 같은 것을하고 싶지 :

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

(전용이 있다면 C# :()

PS :이 델파이 7 (심지어, 알에 더 나쁜)

+1

RTTI는 Delphi 2010에서 훨씬 개선되었습니다. rtti.pas라는 이름의 사용하기 쉬운 단위가 있습니다. 다른 말로하면 d2010으로 전환하면 통증이 줄어 듭니다. –

+0

델파이에는 멋진 새로운 기능이 많이 있습니다. 그러나이 프로젝트에서 나는 정말로 할 수 없습니다 :/-하지만 2010 년 재판을하려고합니다. 내 상사를 납득 시키십시오 : D – Leo

+0

현재 embarcadero가 독일의 roadshow에 있습니다. http://devtracks.de –

답변

4

문자열 속성이 쉬운 경우 말한대로 단위에서 GetStrPropSetStrProp을 호출한다고 가정합니다. GetObjectPropSetObjectProp을 사용하면 클래스 유형 속성을 동일하게 쉽게 만들 수 있습니다. 속성을 필요로

(GetObjectProp(Obj, 'data') as TMyClass).Go; 

은 가지고 :, 당신은 좀 더 직접적으로 갈 수

if Supports(GetObjectProp(Obj, 'data'), IMyInterface, Intf) then 
    Intf.Go; 

당신은 정말 인터페이스를 필요로하지 않는 경우, 당신은 data 속성이 TMyClass 입력이 알고 null 이외의 값

원하는 부동산의 이름을 모르는 경우 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 - 영웅 배지 자격 :) – Leo

2

GetPropInfos (MyClass.ClassInfo)를 호출하여 모든 게시 된 속성의 배열을 가져올 수 있습니다. 이것은 PPropInfo 포인터의 배열이며 GetTypeData를 호출하여 PPropInfo에서 형식 관련 데이터를 가져올 수 있습니다. 그것이 가리키는 레코드는 PTypeData를 반환합니다. 클래스 참조를 찾고 있습니다.