我有三个类,例如(TMyClass1,TMyClass2和TMyClass3)。
我有一个函数,将带有类型名称的字符串作为参数,然后实例化给定类型的类。现在,我正在使用if语句,例如:
if(AFormName = 'xxx1') then
begin
MyClass := MyClass1.Create;
end else if(AFormName = 'xxx2') then
begin
MyClass := MyClass2.Create;
end;
Run Code Online (Sandbox Code Playgroud)
等等..
有没有一种方法可以将类型存储在变量中,以便更改将字符串链接到类型并避免使用它?
如果有帮助,MyClass1,MyClass2和MyClass3都将从另一个类继承...
看一下RTL RegisterClass()和FindClass()/ GetClass()函数,它们正是针对这种情况而设计的,例如:
interface
uses
..., Classes;
type
MyBase = class(TPersistent)
public
constructor Create; virtual;
end;
MyBaseClass = class of MyBase;
MyClass1 = class(MyBase)
public
constructor Create; override;
end;
MyClass2 = class(MyBase)
public
constructor Create; override;
end;
MyClass3 = class(MyBase)
public
constructor Create; override;
end;
...
function MakeMyClass(const Name: string): MyBase;
implementation
function MakeMyClass(const Name: string): MyBase;
begin
Result := MyBaseClass(GetClass(Name)).Create;
end;
...
initialization
RegisterClasses([MyClass1, MyClass2, MyClass3{, ...}]);
end.
Run Code Online (Sandbox Code Playgroud)
然后,您可以执行以下操作:
var
MyObj: MyBase;
begin
MyObj := MakeMyClass('MyClass1');
...
MyObj.Free;
end;
Run Code Online (Sandbox Code Playgroud)
缺点是这些类必须从派生TPersistent。如果您不想使用TPersistent,或者您只想使用不同的名称来创建类对象,则设置自定义工厂并不难,例如,使用TDictionary,例如:
interface
type
MyBase = class
public
constructor Create; virtual;
end;
MyBaseClass = class of MyBase;
MyClass1 = class(MyBase)
public
constructor Create; override;
end;
MyClass2 = class(MyBase)
public
constructor Create; override;
end;
MyClass3 = class(MyBase)
public
constructor Create; override;
end;
...
function MakeMyClass(const Name: string): MyBase;
implementation
uses
System.Generics.Collections, System.SysUtils;
var
MyFactory: TDictionary<string, MyBaseClass>;
function MakeMyClass(const Name: string): MyBase;
begin
Result := MyFactory[Name].Create;
end;
...
initialization
MyFactory := TDictionary<string, TMyBaseCreateFunc>.Create;
MyFactory.Add('xxx1', MyClass1);
MyFactory.Add('xxx2', MyClass2);
MyFactory.Add('xxx3', MyClass3);
finalization
MyFactory.Free;
end.
Run Code Online (Sandbox Code Playgroud)
然后,您可以执行以下操作:
var
MyObj: MyBase;
begin
MyObj := MakeMyClass('xxx1');
...
MyObj.Free;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
142 次 |
| 最近记录: |