如何从接口公开此TList,如IEnumerator或IEnumerator< IFungibleTroll>?我正在使用Delphi XE.
这是我有多远:
unit FungibleTrollUnit; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Generics.Collections; type IFungibleTroll = interface ['{03536137-E3F7-4F9B-B1F5-2C8010A4D019}'] function GetTrollName:String; function GetTrollRetailPrice:Double; end; TFungibleTrolls = class (TInterfacedobject,IEnumerable<IFungibleTroll>) protected FTrolls:TList<IFungibleTroll>; public // IEnumerable function GetEnumerator:IEnumerator<IFungibleTroll>;// // function GetEnumerator:IEnumerator; overload; // find/search app feature requires searching. // this function FindSingleItemByName(aName:String;patternMatch:Boolean):IFungibleTroll; function FindMultipleItemsByName(aName:String;patternMatch:Boolean):IEnumerable<IFungibleTroll>; function FindSingleItemByIdentifier(anIdentifer:String):IFungibleTroll;// use internal non-visible identifier to find an app. constructor Create; property Trolls:TList<IFungibleTroll> read FTrolls; // implements IEnumerable<IFungibleTroll>;?? private end; implementation { TFungibleTrolls } constructor TFungibleTrolls.Create; begin FTrolls := TList<IFungibleTroll>.Create; end; function TFungibleTrolls.FindMultipleItemsByName(aName: String; patternMatch: Boolean): IEnumerable<IFungibleTroll>; begin end; function TFungibleTrolls.FindSingleItemByIdentifier( anIdentifer: String): IFungibleTroll; begin end; function TFungibleTrolls.FindSingleItemByName(aName: String; patternMatch: Boolean): IFungibleTroll; begin end; function TFungibleTrolls.GetEnumerator: IEnumerator<IFungibleTroll>; begin result := FTrolls.GetEnumerator; end; //function TFungibleTrolls.GetEnumerator: IEnumerator; //begin // result := FTrolls.GetEnumerator; // type IEnumerator<IFungibleTroll> or IEnumerator? //end; end.
[DCC错误] FungibleTrollUnit.pas(26):E2252具有相同参数的方法’GetEnumerator’已存在
-要么-
[DCC错误] FungibleTrollUnit.pas(19):E2291缺少接口方法IEnumerable.GetEnumerator的实现
-要么-
[DCC错误] FungibleTrollUnit.pas(19):E2291缺少接口方法IEnumerable.GetEnumerator的实现
似乎我必须声明两种形式的GetEnumerator,如果我声明TFungibleTrolls来实现IEnumerable,但我似乎无法弄清楚如何使用重载,或者没有重载,或使用“方法解析子句”,如这个:
function IEnumerable.GetEnumerator = GetPlainEnumerator; // method resolution clause needed? function GetEnumerator:IEnumerator<IFungibleTroll>; function GetPlainEnumerator:IEnumerator;
这可能看起来像IEnumerable的一个非常基本的用途,并使接口支持迭代,然而,我被卡住了.
更新:似乎当我在没有首先声明List< T>的情况下尝试这样做时,我陷入了由IEnumerable< T>事实引起的裂缝.继承自IEnumerable,我的类必须提供多个,而不是单个get枚举器方法,因为我的类不是通用的,它不能直接“映射”到IEnumerable的要求,除非我使用通用List< T>宣言. Marjan的示例在编译成项目(.dproj .dpr)时有效,但在内置到包(.dproj .dpk)中并在IDE中编译时则不然.它可以在命令行中,在包中运行,但不能在IDE中,在包中运行.
解决方法
不是直接回答你的问题(仍在继续),但这是我为了获得“接口枚举器”而做的,即支持迭代的接口类:
IList<T> = interface(IInterface) [...] function GetEnumerator: TList<T>.TEnumerator; function Add(const Value: T): Integer; end; type TBjmInterfacedList<T> = class(TBjmInterfacedobject,IList<T>) strict private FList: TList<T>; function GetEnumerator: TList<T>.TEnumerator; strict protected function Add(const Value: T): Integer; public constructor Create; override; destructor Destroy; override; end; implementation constructor TBjmInterfacedList<T>.Create; begin inherited; FList := TList<T>.Create; end; destructor TBjmInterfacedList<T>.Destroy; begin FreeAndNil(FList); inherited; end; function TBjmInterfacedList<T>.GetEnumerator: TList<T>.TEnumerator; begin Result := FList.GetEnumerator; end; function TBjmInterfacedList<T>.Add(const Value: T): Integer; begin Result := FList.Add(Value); end;
然后你可以做以下事情:
ISite = interface(IInterface) ... end; ISites = interface(IList<ISite>); ... end; var for Site in Sites do begin ... end;
实现类,如:
TSite = class(TBjmInterfacedobject,ISite) ... end; TSites = class(TBjmInterfacedList<ISite>,ISites) ... end;
更新
上传到的示例项目源
http://www.bjmsoftware.com/delphistuff/stackoverflow/interfacedlist.zip