D2009 TStringlist ansistring

Asked
Viewd5510

17

Началось летнее затишье в деловой сфере, поэтому я начал переход на D2009. Я примерно определил для каждой подсистемы программы, должны ли они оставаться в формате ascii или могут быть в формате Unicode, и начал перенос.

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

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

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

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

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

Дженерики - это большая причина, по которой я купил D2009. Жалко, что они сделали его несовместимым с FPC

  • Вы проводите много вычислений, включая количество байтов в строке и длину строки? Потому что это единственное реальное требование для меня сделать такой переход на более раннюю.

    smok113 июля 2009, 14:57
  • Один из них - да, бинарные версии с обратной совместимостью и версией. Другой (который я еще даже не начал) - это индивидуальная реализация Sax и DOM.

    Но главная причина в том, что я не хочу объяснять клиентам, как открывать текстовые файлы Unicode и т. д. с помощью блокнота и Excel, оставляя их просто старыми, просто старыми.

    Marco van de Voort13 июля 2009, 15:21
  • Я снова озадачен поведением пользователей на SO. Пять пользователей предоставили вдумчивые ответы на этот вопрос, получив как минимум 14 голосов «за» из 71 зрителя, но ни один не проголосовал за этот вопрос. Без вопросов нет, но я счел полезным прочитать Q и As-so +1 от меня. ИМХО, поддержка Delphi включает поддержку информативного обсуждения темы.

    Argalatyr13 июля 2009, 18:26

5 ответов

9

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

 uses
  Generics.Collections;

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

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

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

РЕДАКТИРОВАТЬ: если он все еще компилируется под D2006, вам придется немного подправить. Попробуйте что-то вроде этого:

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

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

  • Код должен по-прежнему компилироваться с D2006 ... Но, возможно, подойдет небольшая оболочка, например, у меня самые последние обновления, потому что это версия электронной доставки программного обеспечения, выпущенная месяц назад. (кроме 3-го обновления справки, которое я установил вручную)

    Marco van de Voort13 июля 2009, 15:19
13

JCL реализует TAnsiStrings и TAnsiStringList в модуле JclAnsiStrings.

2

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

  • Простите, прости, прости. Я был неправ. Это была модификация, которая не включена в Delphi 2009, но ее легко сделать. Я обновлю свой ответ.

    lkessler13 июля 2009, 15:41
  • ansistrings, похоже, не включает tansistringlist. Весь src / dir не использует grep? Это то, на что я надеялся

    Marco van de Voort13 июля 2009, 15:31
  • Я не вижу ни того, ни другого в AnsiStrings.pas или при поиске в исходном каталоге.

    Bruce McGee13 июля 2009, 15:27
9

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 в качестве кодовой страницы, поэтому весь существующий код работает без изменений.

3

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

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

  • Вы должны отредактировать свой вопрос, указав совместимость с предыдущими версиями Delphi.

    Bruce McGee13 июля 2009, 15:30
  • … очевидно, в unicodestring. Около половины типов файлов являются двоичными, кстати.

    Marco van de Voort13 июля 2009, 15:32
  • текстовые файлы, RS232 прямо на месте. Однако настойчивость - это не просто stringlist.savetostream или что-то в этом роде, а кодирование вручную с жесткими требованиями обратной совместимости с версией. Я делаю примерно то же, что вы советуете на верхнем уровне, но я бы предпочел сохранить подсистемы, которые вводят / выводят строки ответа, и интенсивно использовать их внутри, чтобы избежать проблем. Позже, после миграции, я обновляю выбранные до ansistring.

    Marco van de Voort13 июля 2009, 15:17