Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
soerensen3
Beiträge: 104 Registriert: Fr 22. Jun 2012, 01:51
OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
CPU-Target: 64Bit
Wohnort: Bonn
Beitrag
von soerensen3 » So 3. Apr 2016, 20:10
Was stimmt nicht mit folgender Interacedeklaration?
Code: Alles auswählen
interface uses Classes, sysutils; type { gP3DCustomListEnumerator } generic gP3DCustomListEnumerator < TCustomItem: TObject > = class ( TInterfacedPersistent, IEnumerator ) private type TMoveNext = function ( var Index: Integer ) : TCustomItem of object ; private FCurrent: TCustomItem; FCurrentIdx: Integer; FMoveNext: TMoveNext; function GetCurrent( ) : TCustomItem; procedure Reset( ) ; public constructor Create( AMoveNext: TMoveNext ) ; function MoveNext: Boolean; property Current: TCustomItem read GetCurrent; property CurrentIdx: Integer read FCurrentIdx; end ; { gP3DCustomObjectList } generic gP3DCustomObjectList <TCustomItem: TObject> = class ( TInterfacedPersistent, IEnumerable ) //Hier kommt die Fehlermeldung type TP3DCustomObjectListEnumerator = specialize gP3DCustomListEnumerator < TCustomItem >; private FItems: TList; FOnChange: TNotifyEvent; function GetCount: Integer; procedure SetCount( AValue: Integer ) ; function GetItems( Index: Integer ) : TCustomItem; function MoveNext( var Index: Integer ) : TCustomItem; public constructor Create; destructor Destroy; override; function Add( Item: TCustomItem ) : Integer; virtual; procedure Delete( Index: Integer ) ; virtual; function IndexOf( Item: TCustomItem ) : Integer; virtual; procedure Clear( const FreeObjects: Boolean = False ) ; virtual; function GetEnumerator( ) : TP3DCustomObjectListEnumerator; procedure Insert( Index: Integer; Item: TCustomItem ) ; property Items[ Index: Integer ] : TCustomItem read GetItems; default; property OnChange: TNotifyEvent read FOnChange write FOnChange; published property Count: Integer read GetCount write SetCount; end ;
Fehler: p3dgenerics.pas(31,59) Error: No matching implementation for interface method "GetEnumerator:IEnumerator;" found
Meiner Meinung nach habe ich das doch implementiert (Die abgeleitete Klasse gP3DCustomListEnumerator implementiert IEnumerator), aber ich kenne mich noch nicht so gut mit Interfaces aus.
Gruß Johannes
marcov
Beiträge: 1100 Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)
Beitrag
von marcov » Mo 4. Apr 2016, 15:38
gP3DCustomObjectList und TP3DCustomObjectListEnumerator sind Klasse (die Interfaces implementieren, aber immerhin Klassen). IEnumerable.GetEnumerator muss aber ein (bestimmtes) Interface zurückgeben.
soerensen3
Beiträge: 104 Registriert: Fr 22. Jun 2012, 01:51
OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
CPU-Target: 64Bit
Wohnort: Bonn
Beitrag
von soerensen3 » Mo 4. Apr 2016, 23:18
Das stimmt! So klappt es.
Falls es jemanden interessiert, der header sieht jetzt so aus:
Code: Alles auswählen
generic IP3DEnumerator < TCustomItem: TObject > = interface [ '{B873CDC1-491F-4F62-A1F8-CED1C13426C4}' ] function GetCurrent: TCustomItem; function MoveNext: Boolean; procedure Reset; property Current: TCustomItem read GetCurrent; end ; generic IP3DEnumerable < TCustomItem: TObject > = interface [ '{A8D955A0-E3A9-4BF5-8CDF-8A21AB3E2A06}' ] function GetEnumerator: specialize IP3DEnumerator < TCustomItem >; end ; { gP3DCustomListEnumerator } generic gP3DCustomListEnumerator < TCustomItem: TObject > = class ( TInterfacedPersistent, specialize IP3DEnumerator < TCustomItem >) private type TMoveNext = function ( var Index: Integer ) : TCustomItem of object ; private FCurrent: TCustomItem; FCurrentIdx: Integer; FMoveNext: TMoveNext; function GetCurrent( ) : TCustomItem; procedure Reset( ) ; public constructor Create( AMoveNext: TMoveNext ) ; function MoveNext: Boolean; property Current: TCustomItem read GetCurrent; property CurrentIdx: Integer read FCurrentIdx; end ; { gP3DCustomObjectList } generic gP3DCustomObjectList <TCustomItem: TObject> = class ( TInterfacedPersistent, specialize IP3DEnumerable < TCustomItem > ) type TP3DCustomObjectListEnumerator = specialize gP3DCustomListEnumerator < TCustomItem >; private FItems: TList; FOnChange: TNotifyEvent; function GetCount: Integer; procedure SetCount( AValue: Integer ) ; function GetItems( Index: Integer ) : TCustomItem; function MoveNext( var Index: Integer ) : TCustomItem; public constructor Create; destructor Destroy; override; function Add( Item: TCustomItem ) : Integer; virtual; procedure Delete( Index: Integer ) ; virtual; function IndexOf( Item: TCustomItem ) : Integer; virtual; procedure Clear( const FreeObjects: Boolean = False ) ; virtual; function GetEnumerator: specialize IP3DEnumerator < TCustomItem >; //IP3DEnumerator.GetEnumerator = GetEnumerator; procedure Insert( Index: Integer; Item: TCustomItem ) ; property Items[ Index: Integer ] : TCustomItem read GetItems; default; property OnChange: TNotifyEvent read FOnChange write FOnChange; published property Count: Integer read GetCount write SetCount; end ;
Weiß nicht ob das vom Compiler her so gedacht ist mehrer Interfaces (Es ist ja ein Generic) mit der gleichen GUID zu verwenden aber es funktioniert und wenn man die Supports Funktion benutzen will brauch man das ja anscheinend.
Danke!