我倾向于使用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;
答案 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的所有内容。