D2009 TStringlist ansistring

Деловое спокойствие лета началось, поэтому я взял миграцию на D2009. Я грубо определил для каждой подсистемы программы, если они должны оставаться ascii или могут быть unicode и начать портирование.

Все прошло довольно хорошо, все компоненты были в версиях D2009 (некоторые, как VSTView, немного несовместимы, хотя), но теперь у меня возникла проблема, в какой-то части, которая должна оставаться ansistring, я широко использую TStringList, в основном как основная карта.

Есть ли что-то простое для его замены, или я должен просто включить сокращенный список tstringlist, основанный на старом источнике Delphi или FPC?

Я не могу себе представить, что я первый столкнулся с этим?

Изменения должны быть относительно локализованы, поэтому код остается компилируемым с BDS2006, пока я просматриваю траекторию валидации. Несколько ifdefs здесь и там не проблема.  Конечно, string- > ansistring и char → ansichar и т.д. Не учитываются как модификации в моем источнике, так как я все равно должен это делать, и он полностью обратно совместим.

Изменить: мне удалось отработать некоторые вещи в классах читателя/писателя. Это облегчает решение Mason, чем я думал изначально. Я буду рассматривать предложение Габра как резерв.

В общем, причина в том, что я купил D2009. Жаль, что они сделали это FPC несовместимым, хотя

Ответы

Ответ 1

Если по "карте" вы имеете в виду "хеш-таблицу", вы можете заменить ее на общий TDictionary. Попробуйте объявить что-то вроде этого:

uses
  Generics.Collections;

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

Затем просто замените StringLists на TStringMaps нужного типа объекта. (Лучшая безопасность типа получает бесплатно.) Кроме того, если вы хотите, чтобы словарь владел объектами и освобождал их, когда вы закончите, измените его на TObjectDictionary и когда вы вызываете конструктор, передайте [doOwnsValues] на соответствующий параметр.

(BTW, если вы собираетесь использовать TDictionary, убедитесь, что вы загрузили обновление D2009 3. В исходном выпуске были некоторые серьезные ошибки в TDictionary, которые сделали его почти непригодным.)

EDIT: если он все еще должен скомпилироваться под D2006, вам придется немного изменить настройки. Попробуйте что-то вроде этого:

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

Обертка не должна занимать слишком много работы, если вы использовали ее в качестве карты в первую очередь. Вы теряете дополнительную безопасность типов в обмен на обратную совместимость, но вы получаете реальную хеш-таблицу, которая выполняет поиск в O (1) раз.

Ответ 2

JCL реализует TAnsiStrings и TAnsiStringList в блоке JclAnsiStrings.

Ответ 3

TStringList.LoadFromFile/SaveToFile также принимает необязательный параметр типа TEncoding, который позволяет вам использовать TStringList для хранения нужного типа строки.

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

Также обратите внимание, что по умолчанию TStringList использует ANSI в качестве кодовой страницы, чтобы весь существующий код работал так, как он есть.

Ответ 4

Нужно ли этим подсистемам оставаться ansistring или просто как они общаются с внешним миром (RS232, текстовые файлы и т.д.)? Точно так же, как я делаю с С#, я рассматриваю строки в Delphi 2009 как строки, и беспокоюсь только о конверсиях, когда кому-то их нужно.

Это также поможет избежать непреднамеренных неявных преобразований в вашем коде и при вызове методов Windows API, повышая производительность.

Ответ 5

Вы можете изменить классы TStrings и TStringList Delphi 2007 (или ранее) и переименовать их в TAnsiStrings и TAnsiStringList. Вы должны обнаружить, что это очень простая модификация, и это даст вам нужные вам классы.