【问题标题】:How to access RTTI in a class constructor?如何在类构造函数中访问 RTTI?
【发布时间】:2014-09-07 06:14:48
【问题描述】:

此代码不允许:

class constructor TOmniMultiPipelineStage.Create;
var
  RTTIType: TRttiType;
begin
  RTTIType:= TRttiContext.GetType(self);
end;

[dcc32 错误] OtlParallel.pas(5040): E2003 Undeclared identifier: 'self'

该变体也是不允许的:

class constructor TOmniMultiPipelineStage.Create;
var
  RTTIType: TRttiType;
begin
  //Not really what I want because I want the actual type of the class
  //Not a fixed ancestor type 
  RTTIType:= TRttiContext.GetType(TOmniMultiPipelineStage);
end;

[dcc32 Error] OtlParallel.pas(5039): E2076 这种形式的方法调用只允许用于类方法或构造函数

如何在类构造函数中获取类的 RTTI 信息?

自我注意:循环遍历一个类的所有后代:Delphi: At runtime find classes that descend from a given base class?

【问题讨论】:

标签: delphi reflection rtti


【解决方案1】:

使用TObjectClassInfo类方法:

class constructor TMyClass.ClassCreate;
var
  ctx: TRttiContext;
  typ: TRttiType;
begin
  typ := ctx.GetType(ClassInfo);
end;

请注意,我还修正了对GetType 的调用语法,这是一个实例方法,因此必须在TRttiContext 的实例上调用。

对你来说更大的问题是类构造函数对你没有用处。类构造函数是静态的。对于定义它们的类型,它们只执行一次。正如您显然期望的那样,它们不会在派生类的上下文中执行。

对于您在 cmets 中讨论的类变量也是如此。只有一个类 var 的实例。您期待并希望每个派生类都有新的实例。

因此,虽然ClassInfo 回答了您提出的问题,但它对您没有任何实际用处。

【讨论】:

  • 一个相关的问题,如果我继承TMyClass,TMyClass 的类构造函数是否也会为具有正确类型信息的孩子启动?
  • @Johan 类构造函数是静态的,因此您需要为每个子类编写一个新的类构造函数。我的答案中的函数在模块的生命周期中只执行一次。
  • 嗯,这会破坏练习的目的。我猜我必须将 RTTI 查询代码移到普通的构造函数中。但这会很浪费,因为类 var 会被一遍又一遍地设置为相同的值。
  • 我会在这个类构造函数中查询对象的所有后代。
  • 您可以轻松枚举所有类型并对所有类型采取措施。你提到类变量。您需要在所有派生类中重新声明类 var。类 var 有一个实例,而不是每个类一个。
猜你喜欢
  • 2021-09-04
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 2011-09-05
  • 2013-08-06
相关资源
最近更新 更多