I'd like to instantiate a class but I only have its name in a string. Is there a way?
我想实例化一个类,但我只在字符串中有它的名字。有办法吗?
2 个解决方案
#1
This is from Delphi help (Delphi 2006, but also available from at least Delphi 7):
这是来自Delphi的帮助(Delphi 2006,但至少也可以从Delphi 7获得):
Syntax function GetClass(const AClassName: string): TPersistentClass;
语法function GetClass(const AClassName:string):TPersistentClass;
Description Call GetClass to obtain a class from a class name. This class can be used as a parameter to routines that require a class. The Class must be registered before GetClass can find it. Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. Other classes can be registered by calling RegisterClass or RegisterClasses .
描述调用GetClass以从类名称获取类。此类可用作需要类的例程的参数。必须在GetClass找到它之前注册Class。在加载表单时,将自动注册表单声明中引用的表单类和组件类(实例变量)。可以通过调用RegisterClass或RegisterClasses来注册其他类。
Here some sample code. Works as such only because TButton is a TControl and therefore the typecast is valid.
这里有一些示例代码。这样工作只是因为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;
#2
When I needed to do that, I Built my own Object Factory that uses a specially subclassed TStringList, I'm currently using Delphi 7 so the string list class supports only attach a Object to a String, then I got to subclass TStringList to make it possible handle Class Types too, so now I can instantiate a object just passing it's class name to the factory. Works that way:
当我需要这样做的时候,我构建了自己的Object Factory,它使用了一个特殊的子类TStringList,我现在正在使用Delphi 7,因此字符串列表类只支持将一个Object附加到一个String,然后我必须继承TStringList来实现它也可以处理类类型,所以现在我可以实例化一个对象,只是将它的类名传递给工厂。这样工作:
1st - Load a Singleton Object Factory;
2st - Register any object to the factory, could be in the initialization section of the unit;
1st - 加载Singleton对象工厂;第2步 - 将任何对象注册到工厂,可以在单元的初始化部分;
The main Factory's methods could be: isClassRegistered, registerClass, instantiateClass(ClassName: STring): TObject;
Factory的主要方法可以是:isClassRegistered,registerClass,instantiateClass(ClassName:STring):TObject;
This way I can instantiate any object, or use a previous instantiated object, or even, a subset of they.
这样我可以实例化任何对象,或使用先前实例化的对象,甚至是它们的子集。
I rather use a Enumerated type instead of a string to identify a Class.
我宁愿使用枚举类型而不是字符串来标识类。
Remarks: It's a very, very terse example, a completely functional code is more complex, but, belive me, not too much.
备注:这是一个非常非常简洁的例子,一个功能完整的代码更复杂,但是,相信我,而不是太多。
#1
This is from Delphi help (Delphi 2006, but also available from at least Delphi 7):
这是来自Delphi的帮助(Delphi 2006,但至少也可以从Delphi 7获得):
Syntax function GetClass(const AClassName: string): TPersistentClass;
语法function GetClass(const AClassName:string):TPersistentClass;
Description Call GetClass to obtain a class from a class name. This class can be used as a parameter to routines that require a class. The Class must be registered before GetClass can find it. Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. Other classes can be registered by calling RegisterClass or RegisterClasses .
描述调用GetClass以从类名称获取类。此类可用作需要类的例程的参数。必须在GetClass找到它之前注册Class。在加载表单时,将自动注册表单声明中引用的表单类和组件类(实例变量)。可以通过调用RegisterClass或RegisterClasses来注册其他类。
Here some sample code. Works as such only because TButton is a TControl and therefore the typecast is valid.
这里有一些示例代码。这样工作只是因为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;
#2
When I needed to do that, I Built my own Object Factory that uses a specially subclassed TStringList, I'm currently using Delphi 7 so the string list class supports only attach a Object to a String, then I got to subclass TStringList to make it possible handle Class Types too, so now I can instantiate a object just passing it's class name to the factory. Works that way:
当我需要这样做的时候,我构建了自己的Object Factory,它使用了一个特殊的子类TStringList,我现在正在使用Delphi 7,因此字符串列表类只支持将一个Object附加到一个String,然后我必须继承TStringList来实现它也可以处理类类型,所以现在我可以实例化一个对象,只是将它的类名传递给工厂。这样工作:
1st - Load a Singleton Object Factory;
2st - Register any object to the factory, could be in the initialization section of the unit;
1st - 加载Singleton对象工厂;第2步 - 将任何对象注册到工厂,可以在单元的初始化部分;
The main Factory's methods could be: isClassRegistered, registerClass, instantiateClass(ClassName: STring): TObject;
Factory的主要方法可以是:isClassRegistered,registerClass,instantiateClass(ClassName:STring):TObject;
This way I can instantiate any object, or use a previous instantiated object, or even, a subset of they.
这样我可以实例化任何对象,或使用先前实例化的对象,甚至是它们的子集。
I rather use a Enumerated type instead of a string to identify a Class.
我宁愿使用枚举类型而不是字符串来标识类。
Remarks: It's a very, very terse example, a completely functional code is more complex, but, belive me, not too much.
备注:这是一个非常非常简洁的例子,一个功能完整的代码更复杂,但是,相信我,而不是太多。