TStringList wrapper in record

I try to use Delphi TStringList for text processing, 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 creation and liberation for such a general utility class.

Since we now have records with methods, is it possible to wrap a class like TStringList in a Record so that I can simply:

 var TempList: TRecordStringList; begin // blah blah blah do stuff with TempList end; 
+4
source share
3 answers

It is possible. Create an interface that provides the methods / objects you want:

 type IStringList = interface procedure Add(const s: string); // etc. property StringList: TStringList read GetStringList; // etc. end; 

Deploy the interface and wrap the real TStringList :

 type TStringListImpl = class(TInterfacedObject, IStringList) private FStringList: TStringList; // create in constructor, destroy in destructor // implementation etc. end; 

Then write:

 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 is an interface inside the record means that the compiler automatically processes the reference count, calling _AddRef and _Release, since the copies are created and destroyed, so the life cycle is controlled automatically. This works for objects that will never contain a reference to themselves (loop creation). To tally the links, you need different tricks to cycle through the loops in the reference graph.

+15
source

If you are fortunate enough to upgrade to Delphi 2009, then see Barry working with smart pointers .

 TSmartPointer<T: class> = record strict private FValue: T; FLifetime: IInterface; public constructor Create(const AValue: T); overload; class operator Implicit(const AValue: T): TSmartPointer<T>; property Value: T read FValue; end; 

They are really cool, but require universal and anonymous methods. If you have not upgraded to Delphi 2009 , do it now! Moreover, they offer a special BOGO . You also get the Marco Delphi Developer Developer's Guide for free, just for downloading a trial version . I also bought a copy of it.

+4
source

There is another example implemented in CC .

StringList is the same as TStringList, except that it is a value of type. It should not be created, destroyed or placed inside to try / finally. This is done by the compiler for you. There are virtually no special penalties for their work:

 var strings: StringList; astr: string; begin strings.Add('test1'); strings.Add('test2'); aStr := string(strings); RichEdit.Lines.AddStrings(strings); end; 

The code can be used as a template for transferring any TObject as a type of value class.

It already has everything TStringList offers you.

+2
source

All Articles