如何在Delphi 2010中使用RTTI创建对象的实例? [英] How to create an instance of object with RTTI in Delphi 2010?

查看:233
本文介绍了如何在Delphi 2010中使用RTTI创建对象的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As we all known, when we call a constructor of a class like this:

instance := TSomeClass.Create;

Delphi编译器实际上执行以下操作:

The Delphi compiler actually do the following things:


  1. 调用静态NewInstance方法
    分配内存并初始化
    的内存布局。

  2. 调用构造函数方法至
    执行类的初始化

  3. 调用AfterConstruction方法

这很简单了解。但是我不太确定编译器在第二步和第三步中如何处理异常。

It's simple and easy to understand. but I'm not very sure how the compiler handle exceptions in the second and the third step.

似乎没有明确的方法可以使用RTTI构造函数创建实例D2010中的方法。因此我在Spring Framework for Delphi中编写了一个简单的函数来重现创建过程。

It seems there are no explicit way to create an instance using a RTTI constructor method in D2010. so I wrote a simple function in the Spring Framework for Delphi to reproduce the process of the creation.

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%正确。所以请给我指路。谢谢!

I feel it maybe not 100% right. so please show me the way. Thanks!

推荐答案

调用构造函数并将类作为 Self 传递参数(相对于实例)将正确构造类。构造过程包括 NewInstance AfterConstruction 等,您可以在此处手动执行:没有必要。

Invoking the constructor and passing the class as the Self argument (as opposed to an instance) will correctly construct the class. The process of constructing includes the NewInstance, AfterConstruction etc. that you are manually doing here: it's not necessary.

这应该足够了:

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

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

An oddity of Delphi is how it permits constructors to be called on instances as well as classes. This feature is used as a kind of "placement new" (in C++ terminology) for form construction, so that the global form variable (e.g. Form1 by default for the first form) is assigned at the time that the OnCreate constructor gets invoked. Thus, your code doesn't raise an exception. But it is more normal to pass the class rather than the instance as the Self argument.

这篇关于如何在Delphi 2010中使用RTTI创建对象的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆