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 回答
3

Instance参数与的参数SetValue完全相同。因此,您只需要准确传递调用. 即:InstanceGetValueGetValueSL.AsObject

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

关于问题的最后一部分,如果您需要转换SL为具有特定类的对象,TStringList在这种情况下,您可以使用运行时强制转换:

MyStringList := SL.AsObject as TStringList;

但是,这样做反而意味着您不需要首先使用 RTTI。使用我回答的第一部分中的方法是 RTTI 执行您所要求的方法。

于 2012-09-27T11:44:54.663 回答