Вопрос

Я склонен использовать Delphi TStringList для манипулирования текстом, поэтому я пишу много процедур / функций, таких как:

var
  TempList: TStringList;
begin
  TempList:= TStringList.Create;
  try
    // blah blah blah do stuff with TempList   


  finally
    TempList.Free;
  end;
end;

Было бы неплохо отключить создание и освобождение для такого общего служебного класса.

Поскольку теперь у нас есть записи с методами, можно ли обернуть класс, такой как TStringList, в Запись, чтобы я мог просто иметь:

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


end;
Это было полезно?

Решение

Это возможно. Создайте интерфейс, который предоставляет нужные методы / объекты:

type
  IStringList = interface
    procedure Add(const s: string); // etc.
    property StringList: TStringList read GetStringList; // etc.
  end;

Реализуйте интерфейс и сделайте так, чтобы он содержал настоящий TStringList :

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

Затем выполните запись:

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;

Тот факт, что внутри записи есть интерфейс, означает, что компилятор будет обрабатывать подсчет ссылок автоматически, вызывая _AddRef и _Release, когда копии создаются и уничтожаются, поэтому управление временем жизни происходит автоматически. Это работает для объектов, которые никогда не будут содержать ссылку на себя (создание цикла) - для подсчета ссылок требуются различные приемы для преодоления циклов в графе ссылок.

Другие советы

Если вам повезло перейти на Delphi 2009, ознакомьтесь с Работа Барри с умными указателями .

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;

Они действительно классные, но требуют обобщенных и анонимных методов. Если вы не обновились до Delphi 2009 , сделайте это сейчас! Особенно, когда они предлагают свои специальные BOGO . Вы также получаете Справочник разработчика Delphi от Марко только за загрузка пробной версии . Я уже купил его копию.

Есть еще один пример, который уже реализован в CC .

  

StringList совпадает с TStringList за исключением того, что это значение   тип. Это не должно быть создано, разрушено или помещено в   попробовать / наконец. Это сделано компилятором для вас. Есть   практически нет специальных штрафов за производительность для этих работ:

var 
  strings: StringList;
  astr: string;
begin
  strings.Add('test1');
  strings.Add('test2');
  aStr := string(strings);
  RichEdit.Lines.AddStrings(strings);
end;
     

Код можно использовать в качестве шаблона для переноса любого объекта TObject в качестве типа класса значений.

В нем уже есть все для TStringList, доступного для вас.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top