在Delphi中,有没有一种通过类名实例化一个类的方法?

12

我想通过一个字符串来实例化一个类,有什么方法可以做到吗?

2个回答

29

以下内容来自 Delphi 帮助文档(适用于 Delphi 2006,但至少也可适用于 Delphi 7):

语法 function GetClass(const AClassName: string): TPersistentClass;

描述 调用 GetClass 函数通过类名获取一个类。获得的类可以作为需要类参数的例程的参数。在 GetClass 可以找到该类之前,该类必须被注册。当窗体被加载时,对窗体声明(实例变量)中引用的窗体类和组件类会自动注册。通过调用 RegisterClass 或 RegisterClasses 函数,可以注册其他类。

下面是一些示例代码。仅因为 TButton 是 TControl 的子类,所以类型转换才是有效的。

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterClasses([TButton, TForm]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  CRef : TPersistentClass;
  AControl : TControl;
begin
  CRef := GetClass('TButton');
  if CRef<>nil then
  begin
     AControl := TControl(TControlClass(CRef).Create(Self));
     with AControl do
     begin
        Parent := Self;
        Width := 50;
        Height := 30;
     end;
  end;
end;

很棒的解决方案。但现在我遇到了另一个问题。我想要实例化的类是我自己实现接口的类。而且registerClass必须使用持久化类进行调用。有什么想法吗? - Ricardo Acras
你是否可以从TPersistent派生你的类或其祖先? - malach
我不认为是这样的,因为它实现了一个接口并且必须从TInterfaceObject继承。 - Ricardo Acras
2
我发现TInterfacedPersistent非常完美。谢谢。 - Ricardo Acras
不用在意我之前的建议。TInterfacedPersistent 是你想要的。我记得它的存在,但是忘记了它的名字。 - Jim McKeeth
2
如果您不想更改类层次结构,可以编写自己的代码,而无需使用VCL的RegisterClass机制。只需查看Classes.pas中的TRegGroup.GetClass、TRegGroup.RegisterClass等即可。您可以通过删除RegGroups层来简化代码。 - Uli Gerhardt

2
当我需要这样做时,我建立了自己的对象工厂,使用了一个特殊子类化的TStringList。我目前使用的是Delphi 7,所以字符串列表类仅支持将对象附加到字符串上,因此我不得不对TStringList进行子类化,以使其能够处理类类型,因此现在我可以通过将其类名传递给工厂来实例化对象。过程如下:
1. 加载单例对象工厂; 2. 注册任何对象到工厂中,可以在单元的初始化部分中完成;
主要的工厂方法可能包括:isClassRegistered、registerClass和instantiateClass(ClassName: String):TObject;
这样,我就可以实例化任何对象,或使用先前实例化的对象,甚至它们的子集。
我宁愿使用枚举类型而不是字符串来标识一个类。
备注:这只是一个非常简洁的示例,一个完全可用的代码更加复杂,但是相信我,也不会太难。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接