我想使用泛型功能在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模式,以将所需的表单作为Singleton。

这是下一步,但现在我对泛型的CONSTRUCTOR约束有疑问。它要求一个类具有不带参数的构造函数。但是TForm还没有...什么是解决方法?

最佳答案

在我看来,Delphi中的constructor约束几乎没有用。这对您没有实际用处,因为您需要创建TForm后代,并且它们具有接收参数的构造函数。

您应该限制通用类型TTForm派生。

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作为表单实例的所有者。您可能需要更改方法以接收所有者,然后可以将该所有者传递给构造函数。

关于delphi - 如何为TForm后代使用泛型实现Singleton模式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23591966/

10-10 13:51