如何为我的元类中的任何对象调用对象方法? [英] How to call object method for any object in my metaclass?

查看:100
本文介绍了如何为我的元类中的任何对象调用对象方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上有这个对象结构:

I have basically this object structure:

TJSONStructure = class(TObject);

TReqBase = class(TJSONStructure)
private
   token: Int64;
public
   procedure FillWithTemplateData; virtual;
end;

TReqLogin = class(TReqBase)
private
   username,
   password: String;
   module  : Integer;
public
   procedure FillWithTemplateData; override;
end;

procedure TReqBase.FillWithTemplateData;
begin
   token := ...;
end;

procedure TReqLogin.FillWithTemplateData;
begin
   inherited;
   username := ...;
   password := ...;
   module   := ...;
end;

type
   TWebAct = (ttlogin,
              ttsignin);

TReqClass = class of TReqBase;

const
   cWebActStructures: Array[TWebAct] of
   record
      RequestClass : TReqClass;
   end
   = (
      { ttlogin  } (RequestClass: TReqLogin;),
      { ttsignin } (RequestClass: TReqSignIn;)     // Not in definitions above
     ); 

现在我要做:

var
   lWebAct       : TWebAct;
   lRequestClass : TReqClass;
begin
   for lWebAct := Low(TWebAct) to High(TWebAct) do
   begin
      lRequestClass := cWebActStructures[lWebAct].RequestClass;

我想打电话

lRequestClass.FillWithTemplateData;

,以便在lWebAct = ttlogin等时执行TReqLogin.FillWithTemplateData.
但是它不会编译:E2706 This form of method call only allowed for class methods.

in order to execute TReqLogin.FillWithTemplateData when lWebAct = ttlogin etc.
But it won't compile: E2706 This form of method call only allowed for class methods.

我确实理解了原因(编译器消息的文本),但如何解决此问题,以便在lWebAct = ttlogin等时执行TReqLogin.FillWithTemplateData,而不必处理列表中的TReqLogin,TReqSignIn类型的列表.代码(再次)?

I do understand the reason (the text of the compiler message) but how can I fix this so that TReqLogin.FillWithTemplateData gets executed when lWebAct=ttlogin etc without having to handle a list of TReqLogin, TReqSignIn types in the code (again)?

推荐答案

lRequestClass是类引用.您可以在其上调用class方法,但不能调用实例方法. FillWithTemplateData是实例方法.

lRequestClass is a class reference. You can call class methods on it, but not instance methods. And FillWithTemplateData is an instance method.

您需要有一个实例才能调用实例方法.因此,实例化一个:

You need to have an instance to call an instance method. So instantiate one:

var 
  req: TReqBase; 
....
req := lRequestClass.Create; 
try
  req.FillWithTemplateData;
  ...
finally
  req.Free;
end;

如果开发类,以便它们需要在其构造函数中执行工作,则必须向TReqBase引入虚拟构造函数.并在派生类中重写它.这是确保从类引用实例化时派生的构造函数运行的唯一方法.

If you develop the classes so that they need to perform work in their constructors then you must introduce a virtual constructor to TReqBase. And override that in derived classes. That's the only way that you can make sure that the derived constructor runs when you are instantiating from a class reference.

也许您的系统要求实例以其他方式实例化,但我无法从此处得知.无论如何,无论如何实例化,都需要一个实例来调用实例方法.

Perhaps your system requires instances to be instantiated in some other way, I cannot tell from here. No matter what, however you instantiate then, you need an instance to call an instance method.

这篇关于如何为我的元类中的任何对象调用对象方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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