Utilisation des Records Managés sous Delphi Sydney
Publié le 11/08/2020 [Delphi]Une des grosses nouveauté de Sydney au niveau du compilateur est le support des Records Managés.
Cette fonctionnalité est assez intéressante dans son fonctionnement, elle permet d'appeler une fonction automatiquement pour initialiser un Record et une autre pour faire le ménage.
Prenons un exemple simple.
dans cet exemple classique (et bidon) j'instancie un
et voilà ! grâce aux deux opérateurs déclarés,
Alors évidemment ça n'a d'intérêt que si vous utiliser (TStringListRecord) à différents endroits, mais ce n'est qu'un exemple...et on peut aussi imager utiliser un
Cette fonctionnalité est assez intéressante dans son fonctionnement, elle permet d'appeler une fonction automatiquement pour initialiser un Record et une autre pour faire le ménage.
Prenons un exemple simple.
procedure TForm1.Button1Click(Sender: TObject);
var
SL: TStringList;
begin
SL := TStringList.Create;
try
SL.Add('Hello');
SL.Add('World');
ShowMessage(SL.Text);
finally
SL.Free;
end;
end;
dans cet exemple classique (et bidon) j'instancie un
StringList
qui est détruit à la fin de la procédure...mais voici comment éviter le try/finally/end
type
TStringListRecord = record
SL: TStringList;
class operator Initialize(out R: TStringListRecord);
class operator Finalize(var R: TStringListRecord);
end;
class operator TStringListRecord.Initialize(out R: TStringListRecord);
begin
R.SL := TStringList.Create;
end;
class operator TStringListRecord.Finalize(var R: TStringListRecord);
begin
R.SL.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
R: TStringListRecord;
begin
R.SL.Add('Hello');
R.SL.Add('World');
ShowMessage(R.SL.Text);
end;
et voilà ! grâce aux deux opérateurs déclarés,
TStringListRecord
instancie automatiquement un TStringList
qui est libéré en fin de procédure car la variable R est locale.Alors évidemment ça n'a d'intérêt que si vous utiliser (TStringListRecord) à différents endroits, mais ce n'est qu'un exemple...et on peut aussi imager utiliser un
<generic>
pour faire des choses plus évoluées.type
TRecord<T:class,constructor> = record
Instance: T;
class operator Initialize(out R: TRecord);
class operator Finalize(var R: TRecord);
end;
class operator TRecord<T>.Initialize(out R: TRecord);
begin
R.Instance := T.Create;
end;
class operator TRecord<T>.Finalize(var R: TRecord);
begin
R.Instance.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
R: TRecord<TStringList>;
begin
R.Instance.Add('Hello');
R.Instance.Add('World');
ShowMessage(R.Instance.Text);
end;