Generics object and assignment overloading

Generics object and assignment overloading


  TMyObject = class

    property Value: T;


  TIntObject = TMyObject;


  obj: TIntObject;

  int: integer;


  obj := TIntObject.Create;

  obj := 4;  // assigns 4 to obj.value

  int := obj; // resulting in Int being 4


Is it possible to do operator overloads which allows the assignments as outlined above? I know this is not housebroken code – but it would help immensely for code simplicity in the specific context that I want to use it in. If possible, what are the pitfalls? (instances will not be persistent or streamed).

16 thoughts on “Generics object and assignment overloading

  1. You cannot overload assignment.  The closest you can get is to overload the implicit cast operator with operator overloading. Which leads you to this:



      TMyRec = record

        FValue: T;

        class operator Implicit(const Value: T): TMyRec;

        class operator Implicit(const Value: TMyRec): T;


    class operator TMyRec.Implicit(const Value: T): TMyRec;


      Result.FValue := Value;


    class operator TMyRec.Implicit(const Value: TMyRec): T;


      Result := Value.FValue;



      value: TMyRec;

      int: integer;


      value := 666;

      int := value;



    If only you’d asked this on Stack Overflow, others could have benefited in the future, rather than this being lost.

  2. David Heffernan It would be a nicety, not a necessicty. It wouldn’t hurt to get rid of the numerous .Value assignment references.

    MyClass.ThisField.Value := ref.ThisField; //int

    MyClass.ThatField.Value := ref.ThatField; //string


    MyClass.ThisField := ref.ThisField; //int

    MyClass.ThatField := ref.ThatField; // string

    There can be a lot of them.

  3. Lars Fosdal Wait, if you want this to be able to copy field values like that, why not just descend from TPersistent and use Assign?

    edit: sorry, silly friday suggestion. Brain is totally in weekend mode.

  4. These are editor wrappers that I am tinkering with – i.e. lots of once-off declarations.  No point in creating assigns for the umpteen variations of classes and editor combos. All I want to do is to minimize the code – and implicit would have done the job – had it been allowed for classes.

    Code extract

    TSupplierEdit = class(TEditorGrid)


        TRepStatusEdit = TEditorGrid.TEnumComboListEditor;

        TBool = TEditorGrid.TEnumComboListEditor;


    procedure SetSupplier(const Value: TPSDSupplier);


        SupplierId: TIntegerEdit;

        SupplierNo: TStringEdit;

        SupplierName: TStringEdit;

        SupplierGS1No: TStringEdit;

        SupplierGLN: TStringEdit;

        OtherList: TRepStatusEdit;

        Bool: TBool;


        constructor Create(const aGrid: TAdvStringGrid); override;

        property Supplier: TPSDSupplier;


    constructor TSupplierEdit.Create;



      SupplierId := Add(‘Id’);

      SupplierId.ReadOnly := True;

      SupplierNo := Add(‘SupplierNo’);

      SupplierName := Add(‘Name’);

      SupplierGS1No := Add(‘GS1 No’);

      SupplierGLN := Add(‘GLN’);

      Status := AddComboList(‘Status’);

      Status.Value := ersNew; 

      Bool := AddComboList(‘Can do?’);

      Bool.OnElementToString :=



          case Value of

          False: Result := ‘Nope’;

          else Result := ‘Yup’;




    This is where I’d love to get rid of the .value ref.

    procedure TSupplierEdit.SetSupplier(const Value: TPSDSupplier);


      FSupplier := Value;

      SupplierEdit.SupplierId.Value := Supplier.Id;

      SupplierEdit.SupplierNo.Value := Supplier.SupplierNo;

      SupplierEdit.SupplierName.Value := Supplier.SupplierName;

      SupplierEdit.SupplierGS1No.Value := Supplier.SuppliersGS1No;

      SupplierEdit.SupplierGLN.Value := Supplier.SuppliersGLN;

      SupplierEdit.OtherList.Value := ersRetry;

      SupplierEdit.Bool.Value := True;



    No, I don’t want to use RTTI – as that only would work it for some of the use cases – unless I could somehow pass a by reference and extract the property type from it as well as capturing getter and setter.

    I am full of wishful thinking, it seems.

  5. Any approach using a record will not work (or requires some nasty workarounds) or is just not worth it so save 6 characters of optimal code.

    What you are trying here is some kind of operator lifting for the assign operator depending on the right side of the assignment. Delphi does not support that – the closest approach I can think of is really what I did with the observable in knockoff (I also blogged about it) – but it will not be suitable for you because due to the nature of anonymous method types you cannot access any other members on such a type. But that type is not to save 6 characters anyway.

  6. it’d possible if property could be marked as “default” like we do with indexed [] properties, but then, how do you set the obj itself?

    Looking your code, I think Supplier needs some assign method to do SupplierEdit.Assign(Supplier). At least, all .Value:= get isolated, hidden out of view.

Leave a Reply