Domanda

I want to realize Singleton pattern in Delphi 2010 using Generics feature.

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;

I would like to call it like:

var
  test: TTestClass;

...
test := TgrsObj<TTestClass>(test);

Is my approach possible? What should I correct to make it working?

Honestly my final task is to realize Singleton pattern with TForm descendant to have needed forms as singletons.

It is next step but now I have question about CONSTRUCTOR constraint of Generics. It requires a class to have a constructor without parameters. But TForm has not it... What is workaround?

È stato utile?

Soluzione

The constructor constraint in Delphi is pretty much useless in my opinion. And it is of no real use to you since you need to create TForm descendants and they have a constructor that receives a parameter.

You should constrain your generic type T to derive from TForm.

type
  TgrsObj = class
    class function Singleton<T: TForm>(O: T): T; static;
  end;

The implementation would then be:

class function TgrsObj.Singleton<T>(O: T): T;
begin
   Result := O;
   if not Assigned(Result) then
     Result := T(TFormClass(T).Create(nil));
end;

And since you are really just trying to access the virtual TComponent constructor you could make the class more general like this:

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;

Of course, this forces nil as the owner of the form instance. You will probably want to change the method to receive an owner which can then be passed to the constructor.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top