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

Bao*_*Zuo 14 delphi rtti delphi-2010

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

instance := TSomeClass.Create;
Run Code Online (Sandbox Code Playgroud)

Delphi编译器实际上做了以下事情:

  1. 调用静态NewInstance方法来分配内存并初始化内存布局.
  2. 调用构造函数方法来执行类的初始化
  3. 调用AfterConstruction方法

它简单易懂.但我不太确定编译器如何处理第二步和第三步中的异常.

似乎没有明确的方法在D2010中使用RTTI构造函数方法创建实例.所以我在Spring Framework for 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;
Run Code Online (Sandbox Code Playgroud)

我觉得这可能不是100%正确.所以请告诉我方式.谢谢!

Bar*_*lly 18

调用构造函数并将类作为Self参数传递(而不是实例)将正确构造类.施工的过程包括NewInstance,AfterConstruction等你手动来这里干什么:这是没有必要的.

这应该足够了:

Result := constructorMethod.Invoke(instanceType.MetaclassType, arguments);
Run Code Online (Sandbox Code Playgroud)

Delphi的一个奇怪之处在于它如何允许在实例和类上调用构造函数.此功能用作表单构造的一种"放置新"(在C++术语中),以便在调用构造函数时Form1分配全局表单变量(例如,默认情况下为第一种形式)OnCreate.因此,您的代码不会引发异常.但是传递类而不是实例作为Self参数更为正常.