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
如何在Delphi2010中使用RTTI创建对象实例?_Delphi_Delphi 2010_Rtti - Fatal编程技术网

如何在Delphi2010中使用RTTI创建对象实例?

如何在Delphi2010中使用RTTI创建对象实例?,delphi,delphi-2010,rtti,Delphi,Delphi 2010,Rtti,众所周知,当我们调用类的构造函数时,如下所示: instance := TSomeClass.Create; Delphi编译器实际上执行以下操作: 调用静态NewInstance方法 分配内存并初始化 内存布局 调用构造函数方法以 执行类的初始化 调用后构造方法 它简单易懂。但我不太确定编译器在第二步和第三步如何处理异常 似乎在D2010中没有使用RTTI构造函数方法创建实例的显式方法。所以我在Spring框架中为Delphi编写了一个简单的函数来重现创建过程 class function

众所周知,当我们调用类的构造函数时,如下所示:

instance := TSomeClass.Create;
Delphi编译器实际上执行以下操作:

  • 调用静态NewInstance方法 分配内存并初始化 内存布局
  • 调用构造函数方法以 执行类的初始化
  • 调用后构造方法
  • 它简单易懂。但我不太确定编译器在第二步和第三步如何处理异常

    似乎在D2010中没有使用RTTI构造函数方法创建实例的显式方法。所以我在Spring框架中为Delphi编写了一个简单的函数来重现创建过程

    class function TActivator.CreateInstance(instanceType: TRttiInstanceType;
      constructorMethod: TRttiMethod; const arguments: array of TValue): TObject;
    var
      classType: TClass;
    begin
      TArgument.CheckNotNull(instanceType, 'instanceType');
      TArgument.CheckNotNull(constructorMethod, 'constructorMethod');
      classType := instanceType.MetaclassType;
      Result := classType.NewInstance;
      try
        constructorMethod.Invoke(Result, arguments);
      except
        on Exception do
        begin
          if Result is TInterfacedObject then
          begin
            Dec(TInterfacedObjectHack(Result).FRefCount);
          end;
          Result.Free;
          raise;
        end;
      end;
      try
        Result.AfterConstruction;
      except
        on Exception do
        begin
          Result.Free;
          raise;
        end;
      end;
    end;
    

    我觉得可能不是100%正确。所以请给我指路。谢谢

    调用构造函数并将类作为
    Self
    参数传递(与实例相反)将正确构造类。构建过程包括您在此处手动执行的
    NewInstance
    AfterConstruction
    等:这不是必需的

    这应该足够了:

    Result := constructorMethod.Invoke(instanceType.MetaclassType, arguments);
    

    Delphi的一个奇怪之处是它允许在实例和类上调用构造函数。该特征被用作一种“布局新”(C++语言)用于窗体构造,从而在调用“<代码> OnCudio< /Cort>构造函数”的时候分配全局形状变量(例如,默认为第一个窗体的代码> Form 1< /Cord)。因此,您的代码不会引发异常。但是将类而不是实例作为
    Self
    参数来传递更为正常。

    非常感谢!我终于明白了为什么有一个带有类参数的调用重载。@保罗:这个重载也可以用来调用类方法。是的。但是我被参数的名称弄糊涂了。(实例:TClass…)我想我可能发现了一种情况,您需要将实例作为self传递给构造函数。在我的情况下,被调用的构造函数也使用Rtti来填充其字段。当以self形式传递类时,调用的构造函数没有有效的self引用来传递给RttiField.SetValue。将实例作为自修复调用构造函数可以解决这一问题。