在记录中包装TStringList

时间:2009-08-01 15:27:35

标签: delphi records tstringlist

我倾向于使用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;

3 个答案:

答案 0 :(得分:15)

这是可能的。创建一个公开所需方法/对象的接口:

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作为副本被创建和销毁,因此生命周期管理是自动的。这适用于永远不会包含对自身的引用的对象(创建一个循环) - 引用计数需要各种技巧来克服参考图中的循环。

答案 1 :(得分:4)

如果您有幸升级到Delphi 2009,请查看Barry's work with smart pointers

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 special时。您还可以为downloading the trial获取Marco的 Delphi开发人员手册 免费。我也已经购买了它的副本。

答案 2 :(得分:2)

还有另一个例子implemented in 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的所有内容。