针对TStrings和TStringList的接口的代码

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.

Dav*_*nan 6

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班是具有几乎所有的接口提供的好处的抽象类.我认为使用它没有真正的缺点.

  • 为什么不创建一个TIStrings.Strings:TStrings默认属性,而不必包装所有方法? (4认同)