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. Вы должны обнаружить, что это очень простая модификация, и это даст вам нужные вам классы.