首先,如果您打算将 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);