So what will be the preferred way of initializing records?
With a 'factory function':
TMyRecord = record
valueX: integer;
valueY: integer;
end;
function MyRecord(const AValueX, AValueY: integer): TMyRecord;
begin
result.valueX := AValueX;
result.valueY := AValueY;
end;
var
myrec: TMyRecord;
begin
myrec := MyRecord(1, 2);
end;
or a constructor:
TMyRecord = record
valueX: integer;
valueY: integer;
constructor Create(const AValueX, AValueY: integer);
end;
constructor TMyRecord.Create(const AValueX, AValueY: integer);
begin
self.valueX := AValueX;
self.valueY := AValueY;
end;
var
myrec: TMyRecord;
begin
myrec := TMyRecord.Create(1, 2);
end;
I feel that the constructor things more encapsulated, but it makes it easy to get confused when reading code. It makes it look like a class that lack a call to free. It's also more to type...
Why would you prefer one over the other?
I prefer classes, but if I have to use records, I like to treat them as similar as classes as possible. So I use the record constructor.
But there is an annoying bug with records and units. If a function returns a record (with methods), it produces an internal error if you want to access these methods. You can circumvent this by assigning it to another variable:
type
TMyRec = record
..
procedure X;
end;
function GetRec: TMyRec;
procedure Test;
var
r1, r2 : TMyRec;
begin
r1 := GetRec;
r1.X; // internal error
r2 := r1;
r2.X; // No internal error;