8

我有两个问题(其中至少一个是关于 D2010 中的 RTTI 和动态实例化)

  1. 我正在阅读巴里·凯利(Barry Kelly)在一次会议上发表的演讲的衬托,并在第 4 页上找到。13 看起来很有趣的东西:TRTTIConstructor.Invoke。在相邻的要点中,可以找到“动态构造实例而不需要虚拟构造函数和元类”。这似乎是一个很棒的功能(这正是我需要的,顺便说一句)!但是,当我查看 D2010 文档 (ms-help://embarcadero.rs2010/vcl/Rtti.html) 时,我找不到它。被撤销了吗?
  2. 如果类名存储在字符串中,那么创建类实例的最小方法是什么?
4

2 回答 2

10

我认为该功能已被吸收到 TRttiMethod 中。它具有 IsConstructor、IsDestructor 和 IsClassMethod 属性,因此它可以用于“特殊”类型的方法以及普通方法。

至于问题2,试试这样的:

function GetConstructor(val: TRttiInstanceType): TRttiMethod;
var
   method: TRttiMethod;
begin
   for method in val.GetMethods('Create') do
   begin
      if (method.IsConstructor) and (length(method.GetParameters) = 0) then
         exit(method);
   end;
   raise EInsufficientRTTI.CreateFmt('No simple constructor available for class %s ',
                                     [val.MetaclassType.ClassName]);
end;

这会找到调用的最高构造函数Create,它不带参数。如果您知道要查找的内容,则可以对其进行修改以查找具有其他签名的其他构造函数。然后只需调用Invoke结果即可。

于 2010-03-23T14:19:18.457 回答
2

尽管您可以调用 .GetMethod() 来获取构造函数,但您也可以执行以下操作来构造不带构造函数参数的对象实例。

function CreateInstance(aType : TRttiType) : TObject;
begin
  // Option #1
  result := aType.AsInstance.MetaclassType.Create;
  // Option #2
  result := aType.GetMethod('Create').Invoke(aType.AsInstance.MetaclassType,[]);
end;

如果知道基本类型,您可以根据需要对类进行类型转换以传递参数。这是创建组件的示例

result := TComponentClass(aType.AsInstance.MetaClassType).Create(OwnerValue);

于 2010-03-24T04:39:15.513 回答