Wrapping TStringList in a Record
delphi, records, tstringlist
Solution
It's possible. Create an interface that exposes the methods / objects you want:
type
IStringList = interface
procedure Add(const s: string); // etc.
property StringList: TStringList read GetStringList; // etc.
end;
Implement the interface, and have it wrap a real `TStringList`:
type
TStringListImpl = class(TInterfacedObject, IStringList)
private
FStringList: TStringList; // create in constructor, destroy in destructor
// implementation etc.
end;
Then implement the record:
type
TStringListRecord = record
private
FImpl: IStringList;
function GetImpl: IStringList; // creates TStringListImpl if FImpl is nil
// returns value of FImpl otherwise
public
procedure Add(const s: string); // forward to GetImpl.Add
property StringList: TStringList read GetStringList; // forward to
// GetImpl.StringList
// etc.
end;
The fact that there's an interface inside the record means the compiler will handle reference counting automatically, calling _AddRef and _Release as copies get created and destroyed, so lifetime management is automatic. This works for objects that will never contain a reference to themselves (creating a cycle) - reference counting needs various tricks to get over cycles in the reference graph.
Problem
I tend to use Delphi's TStringList for text manipulation, so I write a lot of procedures/functions like: ``` var TempList: TStringList; begin TempList:= TStringList.Create; try // blah blah blah do stuff with TempList finally TempList.Free; end; end; ``` It would be nice to cut out the creation and freeing for such a common utility class. Since we now have records with methods, is it possible to wrap a Class like TStringList in a Record so I could just have: ``` var TempList: TRecordStringList; begin // blah blah blah do stuff with TempList end; ```