我有三个类,例如(TMyClass1,TMyClass2和TMyClass3)。
我有一个函数,该函数将类型名称的字符串作为参数,然后实例化给定类型的类。现在我正在使用if语句,例如:
grid.arrange()
等等。
有没有一种方法可以将类型存储在变量中,以便更改将字符串链接到类型并避免使用它?
如果有帮助,MyClass1,MyClass2和MyClass3都将从另一个类继承...
答案 0 :(得分:8)
看看RTL的RegisterClass()
和FindClass()
/ GetClass()
函数,它们正是针对这种情况而设计的,例如:
const OffersSchema = require('../offers/offersModel').schema
const StoresSchema = require('../stores/storesModel').schema
OffersSchema.storeId = StoresSchema
const FeedsSchema = new Schema({
offerId: OffersSchema,
// ...other fields
})
然后您可以执行以下操作:
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.
缺点是类必须从var
MyObj: MyBase;
begin
MyObj := MakeMyClass('MyClass1');
...
MyObj.Free;
end;
派生。如果您不想使用TPersistent
,或者只想使用不同的名称来创建类对象,则设置自定义工厂并不是很困难,例如通过使用TDictionary
,例如:
TPersistent
然后您可以执行以下操作:
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.