2009-08-01 6 views
4

Ich neige dazu, Delphi TStringList für Textmanipulation zu verwenden, so schreibe ich eine Menge von Prozeduren/Funktionen wie:Wrapping TStringList in einer Bilanz

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 zu befreien für eine solche gemeinsame Nutzungsklasse.

Da wir jetzt Datensätze mit Methoden haben, ist es möglich, eine Klasse wie TStringList in einer Bilanz wickeln und so konnte ich nur:

var 
    TempList: TRecordStringList; 
begin 
    // blah blah blah do stuff with TempList 


end; 

Antwort

15

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; 

die Schnittstelle implementieren, und haben es wickeln echte TStringList:

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

dann den Datensatz implementieren:

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 erhalten und zerstört, so ist die Verwaltung der Lebensdauer automatisch. Dies funktioniert für Objekte, die niemals einen Verweis auf sich selbst enthalten (Erstellen eines Zyklus) - Referenzzählung benötigt verschiedene Tricks, um Zyklen im Referenzgraphen zu überwinden.

+0

Barry: Würde ich mit dieser Idee für alle Datenstrukturen in einem Programm ein Weg, um effektiv die Garbage Collection zu handhaben? – lkessler

+0

Nein; siehe den letzten Satz, über Zyklen in der Referenzkurve. Um dieses Problem zu umgehen, kann sehr schwierig sein. –

+0

Das ist ziemlich cool. Zur Klärung: Gibt es ein Problem nur, wenn die Objektinstanz einen Verweis auf ihre eigene Instanz oder auf eine Instanz derselben Klasse enthält? – HMcG

2

Es ist ein weiteres Beispiel bereits implemented in CC.

StringList ist dasselbe wie TStringList, außer dass es sich um einen Wert handelt. Es muss nicht erstellt, zerstört oder in Versuch/endlich gestellt werden. Dies wird vom Compiler für Sie erledigt. Es gibt praktisch keine besondere Leistung Strafen für diese Arbeit:

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.

+0

Danke Jim, Ich suchte sowohl CC und Google vor dem Posten dieses und fand dieses nicht. Es gibt eine Reihe von Utility-Klassen-Objekten, für die dies praktisch wäre. Obwohl ich RStringList bevorzuge ;-) – HMcG

+0

Dies funktioniert nicht für x64-Architektur, da es scheint InterlockedIncrement/InterlockedDecrement werden nicht von kernel32 (in der 64-Bit-Version) exportiert – flokk

4

Wenn Sie Glück haben, haben Delphi aufgerüstet 2009 dann schauen Sie Barry's work 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; 

Sie sind wirklich cool, aber erfordern generische und anonyme Methoden. Wenn Sie nicht auf Delphi 2009 aktualisiert haben, dann tun Sie es jetzt! Vor allem, während sie ihre BOGO special anbieten. Sie erhalten auch Delphi Entwickler Handbuchkostenlos nur Marco für downloading the trial. Ich habe bereits eine Kopie davon gekauft.

+1

Bereits aktualisiert! Upgrade von Turbo Delphi Pro auf Delphi 2009 Professional, also (soweit es mich betrifft) habe ich es zu einem Schnäppchen gebracht. Das BOGO-Angebot wäre das Sahnehäubchen gewesen, aber ich versuche auch, Prism zu bekommen. – HMcG

+0

Obwohl ich Generics noch nicht einmal berührt habe - so viel zu lernen, so wenig Zeit ................ – HMcG