如何将TRTTIInstanceType obj引用转换为其实际对象引用?

时间:2012-09-27 11:29:19

标签: delphi

我正在尝试使用extented 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**).

2 个答案:

答案 0 :(得分:3)

首先,如果您打算将Rtti用于所有这些任务,我将回答它应该如何正确完成,但在这种情况下,可以避免使用Rtti。 E.g:

由于您使用以下行创建了字符串列表:

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);

答案 1 :(得分:3)

Instance的{​​{1}}参数与SetValue的{​​{1}}参数完全相同。因此,您只需要准确传递调用Instance时已经执行的操作。即GetValue

GetValue

关于问题的最后部分,如果您需要将SL.AsObject转换为具有特定类的对象,在这种情况下为t.GetProperty('Text').SetValue(SL.AsObject, Lines); ,那么您可以使用运行时强制转换:

SL

然而,这样做意味着您不需要首先使用RTTI。使用我的答案的第一部分中的方法是RTTI方式来做你想要的。