众所周知,当我们调用类的构造函数时:
instance := TSomeClass.Create;
Delphi编译器实际上做了以下事情:
>调用静态NewInstance方法
分配内存并初始化
内存布局.
>调用构造方法
执行类的初始化
>调用AfterConstruction方法
这很简单易懂.但是我不太清楚编译器如何在第二和第三步中处理异常.
在D2010中,似乎没有明确的方法来创建使用RTTI构造方法的实例.所以我在Delphi的Spring框架中写了一个简单的函数来重现创建的过程.
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术语中),以便在调用OnCreate构造函数时分配全局形式变量(例如默认为第一个窗体的Form1).因此,您的代码不会引发异常.但是通过类而不是实例作为自变量是更正常的.