для in с интерфейсом

Я пытаюсь просмотреть список объектов, но я просто хочу предоставить интерфейс, реализованный моими объектами.

У меня есть 2 случая: просто перечисление через мой список внутри (что не является большой проблемой, я мог бы просто использовать объект вместо интерфейса) и свойство.

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?


person Florian Koch    schedule 27.11.2014    source источник


Ответы (1)


На первый взгляд, вы можете просто изменить локальную переменную 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

где template равно ITemplate.

person David Heffernan    schedule 27.11.2014
comment
теперь, когда я это вижу.... *facepalm* да, вы совершенно правы, я не должен использовать TObjectList, как я вообще понял эту идею :D thx (: - person Florian Koch; 27.11.2014