for ... in with interface

时间:2014-11-27 16:17:43

标签: delphi interface enumeration delphi-xe6

我试图查看对象列表,但我只是想提供由我的对象实现的接口。

我有两种情况:只是在内部列举我的列表(这不是一个大问题,我可以只使用对象而不是接口)和一个属性。

ITemplate = interface
  ...
end;

TTemplate = class (TInterfacedObject, ITemplate)
  ...
end;

TMyClass = class
strict private
  FTemplates: TObjectList<TTemplate>;
  function GetTemplates: IEnumerable<ITemplate>;
  ...
public
  property Templates: IEnumerable<ITemplate> read GetTemplates;

...

procedure TMyClass.LoopTroughInternally;
var
  template: ITemplate;
begin
  for template in FTemplates do  // isn't working, of course
    foobar(template);
end;

function TMyClass.GetTemplates: IEnumerable<ITemplate>;
begin
  // dunno what to do here...
end;

有没有办法提供这个枚举器而不实现特定的IEnumerable?

1 个答案:

答案 0 :(得分:7)

采用面值,您只需将局部变量template更改为TTemplate类型,然后就可以了。如果此代码是内部代码,那么就没有必要做任何其他事情了。

然而,在我看来,你有更大的问题。

type
  TTemplate = class(TInterfacedObject, ITemplate)
    ...
  end;

....

FTemplates: TObjectList<TTemplate>;

这是一个很大的错误。当您从TInterfacedObject继承时,您说生命周期由接口引用计数管理。这意味着您必须停止使用非引用计数引用。因为它们容易变得陈旧。当您使用TTemplate引用时,您将使用非引用计数引用。您可以使用TObjectList<T>来解决问题,这与生命周期管理有关。

避免这种情况的简单方法是使用接口列表而不是TObjectList<T>

FTemplates: TList<ITemplate>;

现在,你已经完成了,因为你确实可以写

for template in FTemplates do

其中templateITemplate