加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何正确地使接口支持迭代?

发布时间:2020-12-15 09:33:25 所属栏目:大数据 来源:网络整理
导读:如何从接口公开此TList,如IEnumerator或IEnumerator IFungibleTroll?我正在使用Delphi XE. 这是我有多远: unit FungibleTrollUnit;interfaceuses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Generics.Collections;type IFungibl
如何从接口公开此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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读