Bri*_*ost 7 delphi interface tstringlist delphi-xe2
我饶有兴趣地阅读了Nick Hodges关于你为什么要使用界面的博客 ,因为我已经爱上了我编码中更高层次的界面,所以我决定看看如何将它扩展到相当低的水平并调查支持因为这在VCL课程中存在.
我需要的一个常见构造是使用TStringList做一些简单的事情,例如这个代码将一个小文本文件列表加载到一个逗号文本字符串中:
var
MyList : TStrings;
sCommaText : string;
begin
MyList := TStringList.Create;
try
MyList.LoadFromFile( 'c:\temp\somefile.txt' );
sCommaText := MyList.CommaText;
// ... do something with sCommaText.....
finally
MyList.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果我可以使用MyList作为接口编写它似乎是一个很好的简化 - 它将摆脱try-finally并提高可读性:
var
MyList : IStrings;
//^^^^^^^
sCommaText : string;
begin
MyList := TStringList.Create;
MyList.LoadFromFile( 'c:\temp\somefile.txt' );
sCommaText := MyList.CommaText;
// ... do something with sCommaText.....
end;
Run Code Online (Sandbox Code Playgroud)
我看不到定义的IStrings - 当然不是在Classes.pas中,尽管在线编程时有关于它的引用.它存在吗?这是一个有效的简化吗?我正在使用Delphi XE2.
RTL/VCL中没有可以执行所需操作的接口(显示相同的接口TStrings
).如果你想使用这样的东西,你需要自己发明它.
你可以使用这样的包装器实现它:
type
IStrings = interface
function Add(const S: string): Integer;
end;
TIStrings = class(TInterfacedObject, IStrings)
private
FStrings: TStrings;
public
constructor Create(Strings: TStrings);
destructor Destroy; override;
function Add(const S: string): Integer;
end;
constructor TIStrings.Create(Strings: TStrings);
begin
inherited Create;
FStrings := Strings;
end;
destructor TIStrings.Destroy;
begin
FStrings.Free; // don't use FreeAndNil because Nick might see this code ;-)
inherited;
end;
function TIStrings.Add(const S: string): Integer;
begin
Result := FStrings.Add(S);
end;
Run Code Online (Sandbox Code Playgroud)
当然,你会TStrings
在真正的类中包装接口的其余部分.使用这样的包装器类来执行此操作,以便您可以TStrings
通过访问其实例来包装任何类型.
像这样使用它:
var
MyList : IStrings;
....
MyList := TIStrings.Create(TStringList.Create);
Run Code Online (Sandbox Code Playgroud)
您可能更喜欢添加辅助函数来实际执行调用的脏工作TIStrings.Create
.
另请注意,生命周期可能是一个问题.您可能需要此包装器的变体,它不会接管对基础TStrings
实例的生命周期的管理.可以使用TIStrings
构造函数参数进行排列.
我自己,我认为这是一个有趣的思想实验,但不是一个明智的方法.该TStrings
班是具有几乎所有的接口提供的好处的抽象类.我认为使用它没有真正的缺点.