Generics and constructors

Generics and constructors

Fair enough, if you qualify the type to require a constructor

TMyClass = class

private

  property Inner: T;

public;

  procedure InnerCreate;

end;

you must have a parameterless constructor to instantiate T.

TMyClass.InnerCreate;

begin

   Inner := T.Create;

end;

but – If you qualify the type of T with an actual class such as TControl that have a public virtual constructor that takes an argument.

constructor TControl.Create(AOwner: TComponent); override;

You still cannot specify that constructor for T.

TMyClass = class

private

  property Inner: T;

public;

  procedure InnerCreate;

end;

TMyClass.InnerCreate;

begin

   Inner := T.Create(nil); //<– [dcc32 Error] : E2029 ')' expected but 'NIL' found

end;

Why is this not valid?  The method is public, and the actual type of T has been specified.

6 thoughts on “Generics and constructors


  1. Because the constructor constraint means that you have to have a parameterless constructor.  This is something borrowed from C# where the class constraint does not mean T has to be a class but a reference type. But not all reference types have a parameterless constructor.  But in Delphi every class has one (the one from TObject).


    To make your code work you have to write this (and leave out the constructor constraint):


    procedure TMyClass.InnerCreate;


    begin


      TControl(fInner) := TControlClass(T).Create(nil);


    end;

    Like


  2. If you don’t wanna know what exactly T type is and wanna create it, you only can use parameterless constructor (T.create). Once you type cast T to exactly type, you can create it with actual parameters.  Constraint constructor must have class with default constructor, however, since TObject is the root, you always have one. So no error here, but complain you create with parameters.

    Like


  3. Lars Fosdal It calls the constructor that is defined by TControl if you have TControlClass = class of TControl in your code (don’t know if it is predefined, but maybe it is).


    As long as your TControl descendant overrides the constructor of TControl you should be ok.

    Like


  4. Martin Wienold Even if it does not override the TControl constructor he is ok (well unless there is another contructor with different parameters of course). And yes, TControlClass is defined in Controls.pas.


    The technique used here is nothing special to generics and has worked way before generics were introduced into Delphi. If you have a class reference and have the constructor is virtual it calls the latest constructor in the inheritance chain. (in fact that is how Delphi instantiates components that are streamed from the dfm)

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.