2009-07-13 6 views
15

Die geschäftliche Ruhe des Sommers hat begonnen, also habe ich die Migration auf D2009 aufgenommen. Ich habe grob für jedes Subsystem des Programms bestimmt, ob sie ascii bleiben oder Unicode sein und mit der Portierung beginnen sollen.D2009 TStringlist ansiktring

Es ging ziemlich gut, alle Komponenten waren dort in D2009-Versionen (einige, wie VSTView, etwas inkompatibel obwohl), aber ich habe jetzt ein Problem, in einigen Teil muss anisstring bleiben, verwende ich TStringList, meist als eine grundlegende Karte.

Gibt es schon etwas leicht zu ersetzen, oder sollte ich einfach eine Kürzung ansistring tstringlist, basierend auf alten Delphi oder FPC-Quelle?

Ich kann mir nicht vorstellen, dass ich der Erste bin, der darauf reinkommt?

Die Änderungen müssen relativ lokalisiert sein, damit der Code mit BDS2006 kompilierbar bleibt, während ich die Validierungskurve durchlaufe. Ein paar idefdefs hier und da sind kein Problem. Natürlich zählen string-> anisstring und char -> ansichar etc nicht als Modifikationen in meiner Quelle, da ich das sowieso machen muss, und es ist voll rückwärts compat.

Edit: Ich konnte einige der Dinge in Reader/Writer-Klassen wegarbeiten. Das macht Masons Lösung einfacher als ich ursprünglich dachte. Ich werde Gabrs Vorschlag als Fallback berücksichtigen.

Generika ist so ziemlich der Grund, warum ich D2009 gekauft habe. Schade, dass sie es in FPC inkompatibel gemacht haben

+1

Machst du eine Menge Berechnung, einschließlich der Byteanzahl einer Zeichenfolge und der Länge der Zeichenfolge? Denn das ist für mich die einzige echte Anforderung, eine solche Herabstufung vorzunehmen. – smok1

+0

Eins ist ja, versionierte abwärtskompatible Binärversionen. Die andere (die ich noch nicht einmal gestartet habe) ist eine angepasste Sax- und DOM-Implementierung. Aber der Hauptgrund ist, dass ich Kunden nicht erklären möchte, wie man Unicode-Textdateien usw. mit Notizblock und Excel öffnet und es einfach alt, einfach alt lässt. –

+1

Wieder bin ich perplex vom Verhalten der Benutzer auf SO. Fünf Benutzer haben diese Frage mit nachdenklichen Antworten beantwortet, von 71 Zuschauern bisher mindestens 14, aber _not one_ hat die Frage nicht abgestimmt. Keine Frage ist perfekt, aber ich fand es hilfreich, das Q und das As zu lesen - also +1 von mir. IMHO, ** Support Delphi ** beinhaltet unterstützende informative Diskussionen zu diesem Thema. – Argalatyr

Antwort

9

Wenn Sie unter "map" "Hashtabelle" verstehen, können Sie sie durch das generische TDictionary ersetzen. Versuchen Sie so etwas wie dies zu erklären:

uses 
    Generics.Collections; 

type 
    TStringMap<T: class> = TDictionary<ansiString, T>; 

Dann einfach Ihre Stringlisten mit TStringMaps des rechten Objekttypen ersetzen. (Bessere Typ-Sicherheit wird kostenlos eingeführt.) Wenn Sie möchten, dass das Wörterbuch die Objekte besitzt und sie freigibt, wenn Sie fertig sind, ändern Sie es in ein TObjectDictionary. Wenn Sie den Konstruktor aufrufen, übergeben Sie [doOwnsValues] an der geeignete Parameter.

(. BTW, wenn Sie TDictionary verwenden werden, stellen Sie sicher, dass Sie D2009-Update 3. Die ursprüngliche Version herunterladen einige schwere Fehler in TDictionary hatte, dass es fast unbrauchbar gemacht)

EDIT: Wenn es noch zu kompilieren Sie unter D2006, dann müssen Sie die Dinge ein wenig zwicken. so etwas wie dieses versuchen:

type 
    TStringMap = 
{$IFDEF UNICODE} 
    class TDictionary<ansiString, TObject> 
    (Add some basic wrapper functions here.) 
    end; 
{$ELSE} 
    TStringList; 
{$ENDIF} 

Der Wrapper sollte nicht zu viel Arbeit nehmen, wenn Sie es als eine Karte in erster Linie verwendet haben. Sie verlieren die Sicherheit des Extra-Typs als Gegenleistung für die Abwärtskompatibilität, aber Sie erhalten eine echte Hash-Tabelle, die ihre Lookups in O (1) -Zeit erledigt.

+0

Der Code muss kompilieren mit D2006 bleiben ... Aber vielleicht ein kleiner Wrapper, afaik habe ich die neuesten Updates, weil es eine einmonatige elektronische Software-Lieferungsversion ist. (außer help update 3, dass ich von Hand installiert habe) –

+0

Inzwischen spielte ein bisschen mehr, aber TDictionary unterstützt keine Duplikate scheint es. –

3

Müssen diese Subsysteme bleiben oder wie sie mit der Außenwelt kommunizieren (RS232, Textdateien, etc ...)? Genau wie bei C# behandle ich Strings in Delphi 2009 nur als Strings und sorge mich nur um Conversions, wenn jemand anders sie benötigt.

Dies wird auch dazu beitragen, unbeabsichtigte implizite Konvertierungen in Ihrem Code zu vermeiden und beim Aufrufen von Windows-API-Methoden die Leistung zu verbessern.

+0

Textdateien, RS232 sind direkt vor Ort. Die Persistenz ist jedoch nicht einfach stringlist.savetostream oder so, sondern handkodiert mit strengen rückwärtskompatiblen Anforderungen. Ich tue ungefähr das selbe, wie Sie es im Toplevel empfehlen, aber ich würde es vorziehen, Subsysteme beizubehalten, die anistrings ein/ausliefern und intern stark verwenden, um Schwierigkeiten zu vermeiden. Später, nach der Migration, aktualisiere ich ausgewählte anisstring. –

+1

Sie sollten Ihre Frage bearbeiten, um die Kompatibilität mit früheren Delphi-Versionen zu erwähnen. –

+0

... offensichtlich zu Unicodestring. Etwa die Hälfte der Dateitypen sind binär. –

2

Sie können TStrings und TStringList-Klassen von Delphi 2007 (oder früher) ändern und in TAnsiStrings und TAnsiStringList umbenennen. Sie sollten feststellen, dass dies eine sehr einfache Modifikation ist, und dass Sie die Klassen erhalten, die Sie benötigen.

+0

Ich sehe keine von diesen in AnsiStrings.pas oder in einer Suche des Quellverzeichnisses. –

+0

ansistrings scheint tansistringlist nicht zu enthalten. Das ganze src/dir grep nicht drauf? Es ist, was ich gehofft hatte, obwohl –

+0

Entschuldigung, Entschuldigung. Ich habe mich geirrt. Es handelt sich um eine Modifikation, die nicht in Delphi 2009 enthalten ist, aber leicht zu machen ist. Ich werde meine Antwort aktualisieren. – lkessler

12

JCL implementiert TAnsiStrings und TAnsiStringList in der JclAnsiStrings-Einheit.

8

TStringList.LoadFromFile/SaveToFile nehmen Sie auch einen optionalen Parameter vom Typ TEncoding, mit dem Sie TStringList verwenden können, um jede Art von Zeichenfolge zu speichern, die Sie möchten.

procedure LoadFromFile(const FileName: string; Encoding: TEncoding); overload; virtual; 
procedure SaveToFile(const FileName: string; Encoding: TEncoding); overload; virtual; 

Beachten Sie auch, dass TStringList standardmäßig ANSI als Codepage verwendet, sodass der gesamte vorhandene Code so funktioniert wie er.

+0

(einige Verzögerung in dieser Zeile) Wie gesagt, ich benutze tstringlist als Basis-MAP, also habe ich nicht über diese Methoden streamen, da alle Linien assoziierte Objekte haben [] –

Verwandte Themen