How to serialize a TList of objects with Delphi

Posted on lun 20 agosto 2012 in Delphi, Delphi XE2, Embarcadero, Programming, RTTI

Some weeks ago a customer asked to me if it is possibile serialize a TList of objects. “Hey, you should use a TObjectList for this”, I said, but he absolutely needs (I dont know why) of a TList.

This is the (simple) sample code tested with Delphi XE2 Update4. Enjoy.

``` {language="delphi"}

unit Unit4;

interface

uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type TForm4 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;

TPerson = class private FName: String; procedure SetName(const Value: String); published property Name: String read FName write SetName; end;

var Form4: TForm4;

implementation

uses Contnrs, dbxjson, dbxjsonreflect;

{$R *.dfm}

procedure TForm4.Button1Click(Sender: TObject); var list: TList; m: TJSONMarshal; json: TJSONObject; p1: TPerson; p2: TPerson; begin p1 := TPerson.Create; p2 := TPerson.Create; try p1.Name := 'Daniele Teti'; p2.Name := 'Peter Parker'; list := TList.Create; try list.Add(p1); list.Add(p2);

  m := TJSONMarshal.Create;
  try
    // Register a specific converter for field FList
    m.RegisterConverter(TList, 'FList', function(Data: TObject; Field: String): TListOfObjects
      var
        l: TList;
        j: integer;
      begin
        l := Data as TList;
        SetLength(Result, l.Count);
        for j := 0 to l.Count - 1 do
          Result[j] := TObject(l[j]); // HardCast from pointer
      end);

    json := m.Marshal(list) as TJSONObject;
    try
      Memo1.Lines.Text := json.tostring;
    finally
      json.free;
    end;
  finally
    m.free;
  end;
finally
  list.free;
end;

finally p1.free; p2.free; end; end;

{ TPerson }

procedure TPerson.SetName(const Value: String); begin FName := Value; end;

end.

The output is, as expected, the following:

``` {language="javascript"}
{"type":"System.Classes.TList","id":1,"fields":{"FList":[{"type":"Unit4.TPerson","id":2,"fields":{"FName":"Daniele Teti"}},{"type":"Unit4.TPerson","id":3,"fields":{"FName":"Peter Parker"}}],"FCount":2,"FCapacity":4}}