【问题标题】:How to create an instance of object with RTTI in Delphi 2010?如何在 Delphi 2010 中使用 RTTI 创建对象实例?
【发布时间】:2011-03-05 08:52:40
【问题描述】:

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

instance := TSomeClass.Create;

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

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

简单易懂。但是我不太清楚编译器在第二步和第三步中是如何处理异常的。

在 D2010 中似乎没有使用 RTTI 构造方法创建实例的显式方法。所以我在Spring Framework中为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% 正确。所以请给我指路。谢谢!

【问题讨论】:

    标签: delphi delphi-2010 rtti


    【解决方案1】:

    调用构造函数并将类作为Self 参数(而不是实例)传递将正确构造类。构建过程包括NewInstanceAfterConstruction等你这里手动做的:没必要。

    这应该足够了:

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

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

    【讨论】:

    • 非常感谢!我终于明白了为什么 Invoke 有一个类参数的重载。
    • @Paul:这个重载也可以用来调用方法。
    • 是的。但是我对参数的名称感到困惑。 (实例:TClass...)
    • 我想我可能发现了一种情况,你需要将实例作为 self.在我的情况下,调用的构造函数也使用 Rtti 来填充其字段。当将类作为 self 传递时,调用的构造函数没有有效的 self 引用来传递给 RttiField.SetValue。使用实例调用构造函数作为自我修复此问题。
    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多