Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi: why complain about missing method implementation?

I'd like to use IEnumerator<T> instead of IEnumerator for a list I'm building. I've tried the following

IMyList = interface(IEnumerator<TElement>)
  procedure Add(Element: TElement);
end;

TMyList = class(TInterfacedObject, IMyList )
private
  function GetCurrent: TElement;
  function MoveNext: Boolean;
  procedure Reset;
public
  property Current: TElement read GetCurrent;
  procedure Add(Element: TElement);
end;

but to my amazement I'm being told that TMyList doesn't implement GetCurrent. Why is the compiler telling me that GetCurrent is missing when it is clearly not? (For the record, GetCurrent is implemented, only omitted here for brevity.) Thanks!

like image 907
conciliator Avatar asked Aug 16 '12 09:08

conciliator


1 Answers

IEnumerator<T> inherites from IEnumerator interface. Both of them have GetCurrent() method, and one of them is usual method and second is generics T method;

so in your class you have to implement both of them getCurrent():TObject (from IEnumerator) and getCurrent():T (from IEnumerator<T>);

one small problem is that both methods have the same parameters and you can't simply declare both of them. so you should use aliases:

  function getCurrentItem() : TElement; //actual method for IEnumerator<T>
  function GetCurrent():TObject;  //method for IEnumerator
  function IMyList.GetCurrent = getCurrentItem; //alias

Take a look at Method Resolution Clause at docwiki http://docwiki.embarcadero.com/RADStudio/en/Implementing_Interfaces

so, in your case, code should look like (I marked all methods Abstract):

TElement = class(TObject)
end;

IMyList = interface(IEnumerator<TElement>)
  procedure Add(Element: TElement);
end;

TMyList = class(TInterfacedObject, IMyList )
private
  function getCurrentItem() : TElement; virtual; abstract;

  function IMyList.GetCurrent = getCurrentItem;
  function GetCurrent():TObject;  virtual; abstract;

  function MoveNext(): Boolean;   virtual; abstract;
  procedure Reset(); virtual; abstract;
public
  property Current: TElement read GetCurrentItem;
  procedure Add(Element: TElement); virtual; abstract;
end;
like image 84
teran Avatar answered Nov 15 '22 08:11

teran