繁体   English   中英

根据类类型在运行时创建Delphi对象

[英]Creating Delphi Objects at runtime based on class type

是否可以通过调用方法根据类型在运行时创建对象。

我想要实现的是

var
  lForm1 : TForm;
  lForm2 : TForm;
begin
  CreateObjects([lForm1, lForm2]);
  // After this call I have the variables initialized and I can use them.
end;

问题中没有足够的信息。

表单对象(在问题中)的“类型”从何而来? 它只是类型名称吗? CreateObjects()如何发现每个对象所需的类型?

它不能来自传入的对象引用的“类型”,因为它可能是(并且几乎肯定会是您的示例中所定义的)仅仅是基本类型,所需的具体类型最终将从该基本类型派生。

没有有关您的特定实施目标和约束的更详细的信息,就不可能获得完整而具体的答案。

但是,总的来说,您可以通过将虚拟构造函数和VCL提供的RegisterClass / FindClass基础结构相结合来实现。

简而言之,您将拥有一个基类,该基类引入了用于实例化您的类的公共构造函数[对于TComponent派生类,它已经以Create( Owner:TComponent构造函数的形式存在]。

然后,在运行时,您可以使用FindClass( 'TClassName'获得对任何(注册)类的引用。 这将返回一个类引用,您可以通过该类引用调用适当的虚拟构造函数:

  type
    TFoo = class ....
    TFooClass = class of TFoo;

    // etc


  var
    someClass: TFooClass;
    someObj: TFoo;
  begin
    someClass := TFooClass(FindClass('TFooDerivedClass'));
    someObj := someClass.Create(nil);
      :

注意在上面的那TFooDerivedClass是最终从TFooClass导出(并且假设为简单起见,以依次从TComponent派生和实例化与在这种情况下一个NIL所有者)的类。 可以使用FindClass()找到已经在类型系统中注册的类。 这包括应用程序中某些DFM引用的任何控件或组件类。 可以使用RegisterClass()显式注册需要注册的任何其他类。

您的特定应用程序如何标识所涉及的对象的类型以及类型名称到其他任意标识系统的映射是您必须注意的实现细节。

未经测试的概念代码:

function instantiate(var instancevars : array of tobject;
              const classtypes : array of TBaseClassType):boolean;

begin
  if (length(instancevars)=0) or (length(instancevars)<>length(classtypes)) then
    exit(false);
  for i:=0 to length(instancevars)-1 do
     instancevars[i]:=classtypes[i].create;
  result:=true;
end;

然后使用

instantiate([lform1,lform2],[tform1,tform2]); 

使它工作。

为此,请注意,“ TBaseClassType”必须是用于此函数的所有类的某个基类,并且必须具有虚拟构造函数(例如TPersistent?)。 可能还需要更正.create行(例如add(NIL))

您无法从变量获取类型,该信息仅在编译时可用。

引用您对Henk的回答的评论:

那就是我不想做的。 我有很多服务器端方法,我在运行时创建了很多控件,我想知道像上面那样创建对象会减少代码。

“很多”是什么意思?

如果您要表示很多完全相同类型的组件(例如:“ but1,but2,but3,.. but55:TButton;”),请更改代码并使用数组来表示变量-然后可以进行简单循环创建它们。

如果您指的是许多不同类型的组件(例如:but1:TAnimatedButton; but2:TFlatButton; but3:T3DButton;),我看不到任何简单的方法可以做到这一点,我想您会创建一个小的调试地狱比什么都重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM