我希望使用泛型功能在Delphi 2010中实现Singleton模式。
type
TgrsObj = class
class function Singleton<T: class, constructor>(O: T): T; static;
end;
class function TgrsObj.Singleton<T>(O: T): T;
begin
if O = nil then
O := T.Create;
Result := O;
end;
我想称之为:
var
test: TTestClass;
...
test := TgrsObj<TTestClass>(test);
我的方法可行吗?我应该纠正什么才能让它发挥作用?
老实说,我最后的任务是通过TForm后代实现Singleton模式,将所需的形式作为单身。
这是下一步,但现在我对泛型的CONSTRUCTOR约束有疑问。它需要一个类来拥有一个没有参数的构造函数。但是TForm没有它......什么是变通方法?
答案 0 :(得分:3)
在我看来,Delphi中的constructor
约束几乎没用。它并没有真正使用,因为你需要创建TForm
后代,并且它们有一个接收参数的构造函数。
您应该将通用类型T
限制为从TForm
派生。
type
TgrsObj = class
class function Singleton<T: TForm>(O: T): T; static;
end;
然后实施:
class function TgrsObj.Singleton<T>(O: T): T;
begin
Result := O;
if not Assigned(Result) then
Result := T(TFormClass(T).Create(nil));
end;
由于您实际上只是尝试访问虚拟TComponent
构造函数,因此可以使类更加通用:
type
TgrsObj = class
class function Singleton<T: TComponent>(O: T): T; static;
end;
class function TgrsObj.Singleton<T>(O: T): T;
begin
Result := O;
if not Assigned(Result) then
Result := T(TComponentClass(T).Create(nil));
end;
当然,这会强制nil
作为表单实例的所有者。您可能希望更改方法以接收所有者,然后可以将其传递给构造函数。