Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 德尔福2010:trtti发生了什么?_Delphi_Delphi 2010_Rtti - Fatal编程技术网

Delphi 德尔福2010:trtti发生了什么?

Delphi 德尔福2010:trtti发生了什么?,delphi,delphi-2010,rtti,Delphi,Delphi 2010,Rtti,我有两个问题(其中至少一个是关于D2010中的RTTI和动态实例) 我在读巴里·凯利写的a的箔纸,在p。13一些看起来非常有趣的东西:TRTTIConstructor.Invoke。在相邻的要点中,我们发现“动态构造实例,而不需要虚拟构造函数和元类”。这似乎是一个伟大的功能(这正是我需要的,顺便说一句)!然而,当我查看D2010文档时(ms-help://embarcadero.rs2010/vcl/Rtti.html),我找不到。它被撤销了吗 如果类名存储在字符串中,那么创建类实例的最小方法是

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

  • 我在读巴里·凯利写的a的箔纸,在p。13一些看起来非常有趣的东西:
    TRTTIConstructor.Invoke
    。在相邻的要点中,我们发现“动态构造实例,而不需要虚拟构造函数和元类”。这似乎是一个伟大的功能(这正是我需要的,顺便说一句)!然而,当我查看D2010文档时(ms-help://embarcadero.rs2010/vcl/Rtti.html),我找不到。它被撤销了吗
  • 如果类名存储在字符串中,那么创建类实例的最小方法是什么

  • 我认为这个功能已经被吸收到了trtti方法中。它具有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

    尽管可以调用.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;
    
    如果知道基类型,您可以根据需要键入cast类以传递参数。 下面是一个创建组件的示例


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

    再次感谢梅森!你(和其他在SO的人)几乎填补了文档空白。非常感谢请帮忙。我参加了那个演讲,D2010当时还在测试阶段。从那时到最终版本,似乎有一些事情发生了变化。我不知道为什么他被除掉了。那将非常有用!谢谢你,罗伯特!对于我目前的项目,我事先知道基本类型,所以你答案中的最后一行就是医生要的。(+1)但是,当我运行Button:=TButton(RType.ClassType).Create(self)时,我确实会遇到访问冲突;其中Button:TButton和self是所有者表单,RType:TRTTIType由RType:=RContext.FindType('StdCtrls.TButton')创建;(并且已经创建了上下文)。我做错了什么?试试这个:按钮:=TComponentClass(RType.AsInstance.MetaclassType);谢谢你,维勒克。唉,我仍然会遇到访问冲突。我想我应该就此单独发表一篇文章。也许RContext.FindType('StdCtrls.TButton')返回nil?如果是这样的话,在项目的表单中添加一个按钮,使tbuttonrtti包含在可执行文件中。无论如何,我已经在表单上有了一个按钮。无论如何,它现在不在我的列表的顶部,因为我需要动态创建的类是我编写的一些自定义类(创建得很好)。然而,不久以后的某一天,我需要在飞行中创建一个TButton,所以我一定要研究它。