3

こんにちは、まず私の下手な英語で申し訳ありません。以下を考慮してください (実際のコードではありません)。

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 にあります (さらに悪いことはわかっています)。

4

2 に答える 2

4

あなたが言うように、文字列プロパティが簡単な場合、私はあなたがユニットから呼び出しGetStrPropていると仮定します。クラスタイプのプロパティは、とを使用して同様に簡単にすることができます。SetStrPropTypInfoGetObjectPropSetObjectProp

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

インターフェイスが本当に必要ではなく、dataプロパティのタイプがであることがわかっているTMyClass場合は、もう少し直接アクセスできます。

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

そのためには、プロパティに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;
于 2009-09-09T00:22:30.587 に答える
2

GetPropInfos(MyClass.ClassInfo) を呼び出すと、発行されたすべてのプロパティの配列を取得できます。これは PPropInfo ポインターの配列です。また、PTypeData を返す GetTypeData を呼び出すことで、PPropInfo から型固有のデータを取得できます。それが指すレコードには、クラス参照について探している情報が含まれています。

于 2009-09-08T23:02:56.517 に答える