3

拡張RTTI機能を使用しようとしていますこれは私が立ち往生しているところです。

t := (c.FindType('Classes.TStringList') as TRttiInstanceType);
SL := t.GetMethod('Create').Invoke(t.MetaclassType,[]);
t.GetMethod('Add').Invoke(SL,['Hello Do you like my hat?']);
Lines := t.GetProperty('Text').GetValue(SL.AsObject);

今までは正常に動作しました今は値を変更したい

Lines := 'Test';

t.GetProperty('Text').SetValue(**?**,Lines);

ここで、TRTTIinstancetype参照または実際のオブジェクト参照を指定する必要があります。実際のオブジェクトが参照している場合、どのようにそれを与えるのでしょうか。

TestStringList := t(**how will i get the actual object from this TRTTIinstancetype**).
4

2 に答える 2

3

まず第一に、これらすべてのタスクに Rtti を使用する場合は、正しく行う方法についてお答えしますが、この場合、Rtti の使用を避けることができます。例えば:

この行で文字列リストを作成しているので:

SL := t.GetMethod('Create').Invoke(t.MetaclassType,[]);

後で TStringlist として使用でき、Rtti を使用する必要はありません。

var
  SL: TStringList;
...
begin
...
    SL := (t.GetMethod('Create').Invoke(t.MetaclassType,[]).ASObject) as TStringList;

したがって、次のように呼び出すことができます。

SL.Text := Lines;

それ以外の:

t.GetProperty('Text').SetValue(SL.AsObject,Lines);

しかし、これらすべてのタスクに Rtti を使用したい場合は、次のようなことはすべきではありません。

SL := t.GetMethod('Create').Invoke(t.MetaclassType,[]);

Create メソッドがコンストラクターでない場合はどうなるでしょうか。TStringList では問題ありませんが、他の型では失敗する可能性があります。Rtti を使用してオブジェクトを作成するための別の関数を用意するか、このタスクにはプレーンな TClass を使用することをお勧めします。

パラメータなしでコンストラクタを呼び出したい場合:

SL := t.MetaclassType.Create;

別のオプション:

function CreateType(AType: TRttiType): TObject;
var
  AMethCreate: TRttiMethod;
  instanceType: TRttiInstanceType;
begin
  if AType.IsInstance then
  begin
    for AMethCreate in AType.GetMethods do
    begin
      if (AMethCreate.IsConstructor) and (Length(AMethCreate.GetParameters) = 0) then
      begin
        instanceType := AType.AsInstance;
        Result := AMethCreate.Invoke(instanceType.MetaclassType, []).AsObject;

        Exit;
      end;
    end;
  end;
  Result := nil;
end;

...

var
  SL: TObject;

SL := CreateType(c.FindType('Classes.TStringList')); 

...

t.GetProperty('Text').SetValue(SL,Lines);
于 2012-09-27T11:42:15.310 に答える