Wrapping TStringList in einem Datensatz
-
06-07-2019 - |
Frage
Ich neige dazu, Delphi TStringList für Textmanipulation zu verwenden, so schreibe ich eine Menge von Prozeduren / Funktionen wie:
var
TempList: TStringList;
begin
TempList:= TStringList.Create;
try
// blah blah blah do stuff with TempList
finally
TempList.Free;
end;
end;
Es wäre schön, die Schöpfung zu schneiden und für eine solche gemeinsame Utility-Klasse zu befreien.
Da wir jetzt Datensätze mit Methoden haben, ist es möglich, eine Klasse wie TStringList in a wrap Nehmen Sie so konnte ich nur noch:
var
TempList: TRecordStringList;
begin
// blah blah blah do stuff with TempList
end;
Lösung
Es ist möglich. Erstellen Sie eine Schnittstelle, die die Methoden aussetzt / Objekte, die Sie wollen:
type
IStringList = interface
procedure Add(const s: string); // etc.
property StringList: TStringList read GetStringList; // etc.
end;
Implementieren Sie die Schnittstelle zur Verfügung und eine echte TStringList
wickeln:
type
TStringListImpl = class(TInterfacedObject, IStringList)
private
FStringList: TStringList; // create in constructor, destroy in destructor
// implementation etc.
end;
Dann implementieren, um die Aufzeichnung:
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;
Die Tatsache, dass es eine Schnittstelle innerhalb des Datensatzes bedeutet, dass der Compiler automatisch Referenzzählung behandelt, ruft _AddRef und _Release als Kopien erstellt bekommen und zerstört, so Lebensdauer-Management erfolgt automatisch. Dies funktioniert für Objekte, die nie einen Verweis auf sich selbst enthalten (ein Kreislauf entsteht.) - Referenzzählung verschiedene Tricks muss über Zyklen in der Referenzkurve erhalten
Andere Tipps
Wenn Sie das Glück haben, zu Delphi 2009 aufgerüstet zu haben, dann schauen Sie Barry Arbeit mit Smart-Pointer .
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;
Sie sind wirklich cool, aber erfordern Generics und anonyme Methoden. Wenn Sie nicht aktualisiert haben, um Delphi 2009 , dann tun Sie es jetzt! Vor allem während sie bieten ihren BOGO besondere . Sie erhalten auch Marco Delphi Entwickler-Handbuch kostenlos nur Download der Testversion . Ich kaufte bereits eine Kopie davon zu.
Es ist ein weiteres Beispiel bereits in CC umgesetzt werden.
String ist die gleiche wie TStringList, außer dass es ein Wert ist Art. Es hat nicht innerhalb erstellt, zerstört oder gestellt werden try / finally. Dies wird durch den Compiler für Sie erledigt. Es gibt praktisch keine besonderen Leistungseinbußen für diese arbeiten:
var strings: StringList; astr: string; begin strings.Add('test1'); strings.Add('test2'); aStr := string(strings); RichEdit.Lines.AddStrings(strings); end;
Der Code kann als Vorlage verwendet werden, um jede TObject als Wert Klassentyp zu wickeln.
Es hat bereits alles für eine TStringList für Sie ausgesetzt sind.