代码之家  ›  专栏  ›  技术社区  ›  Wim ten Brink

枚举自定义数组以便在中使用

  •  0
  • Wim ten Brink  · 技术社区  · 14 年前


    type
      TXmlFileList = class( TInterfacedObject )
      private
        type
          TItem = class( TInterfacedObject )
          strict private
            FCaption: string;
          protected
            constructor Create( const ACaption: string; const AXML: WideString );
          public
            destructor Destroy; override;
            property Caption: string read FCaption;
          end;
      strict private
        FXmlFiles: array of TXmlFileList.TItem;
      strict protected
        function GetXmlFile( index: Integer ): TXmlFileList.TItem;
      public
        constructor Create( );
        destructor Destroy; override;
        function Add( const ACaption: string; const AXML: WideString ): Integer; overload;
        function Add( const AFilename: string ): Integer; overload;
        function Count: Integer;
        procedure Clear;
        property XmlFile[ index: Integer ]: TXmlFileList.TItem read GetXmlFile; default;
      end;
    

    看起来很有趣?:-)我知道,但我想向外界隐藏TXmlFile类的定义。基本上,TXmlFileList类允许我简单地引用XmlFileList[I]以获取位置I处的文件。工作良好。

    但现在我想循环遍历TXmlFileList.TItem元素,所以必须公开TXmlFileList.TItem类。不过,这还不够。在TXmlFileList类中也需要一个枚举器!
    如何创建枚举器?



    你可能想知道我为什么要用这个复杂的结构。嗯,它可能很复杂,但它将被其他一些开发人员使用,我不想提供比他们需要的更多的方法。这样,我只给他们方法“Add”、“Clear”和“Count”循环遍历列表,以及在TItem本身上定义的任何属性。他们不需要更多,虽然我可能会添加更多的功能以后。。。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Wim ten Brink    14 年前

    找到了!我需要创建一个新的类,我称之为TItemEnumerator,我还将其包含在TXmlFileList类中,紧跟在TItem之后:

        type
          TItemEnumerator = class( TObject )
          strict private
            FOwner: TXmlFileList;
            FIndex: Integer;
          protected
            constructor Create(AOwner: TXmlFileList);
          public
            function GetCurrent: TItem;
            function MoveNext: Boolean;
            property Current: TItem read GetCurrent;
          end;
    

    实现很简单,只是TXmlFileList的一个附加方法:

        function GetEnumerator: TItemEnumerator;
    

    最后,将类公开给外部世界,我将其添加到TXmlFileList中:

    type TXmlFile = TXmlFileList.TItem;
    


    它产生了以下代码:

    type
      TXmlFileList = class( TInterfacedObject )
      private
        type
          TItem = class( TInterfacedObject )
          strict private
            FCaption: string;
          protected
            constructor Create( const ACaption: string; const AXML: WideString );
          public
            destructor Destroy; override;
            property Caption: string read FCaption;
          end;
        type
          TItemEnumerator = class( TObject )
          strict private
            FOwner: TXmlFileList;
            FIndex: Integer;
          protected
            constructor Create(AOwner: TXmlFileList);
          public
            function GetCurrent: TItem;
            function MoveNext: Boolean;
            property Current: TItem read GetCurrent;
          end;
      strict private
        FXmlFiles: array of TXmlFileList.TItem;
      strict protected
        function GetXmlFile( index: Integer ): TXmlFileList.TItem;
      public
        type TXmlFile = TXmlFileList.TItem;
        constructor Create( );
        destructor Destroy; override;
        function Add( const ACaption: string; const AXML: WideString ): Integer; overload;
        function Add( const AFilename: string ): Integer; overload;
        function Count: Integer;
        function GetEnumerator: TItemEnumerator;
        procedure Clear;
        property XmlFile[ index: Integer ]: TXmlFileList.TItem read GetXmlFile; default;
      end;
    

    是的,当你看到它的时候,你可以开始挠头,但是这是一个很好的解决方案,可以把许多功能隐藏起来,不让没有经验的开发人员看到!现在他们只看到他们需要看到的。(希望他们永远不要看这个源代码!)
    我只是想我需要写更多的代码。。。


    为什么要用不同的名称来显示滴度类型?实际上,这些类又被包装在一个更大的类TXmlManager中,该类还处理样式表、转换、验证和其他一些事情。TXmlFile实际上是在TXmlManager级别公开的,而不是TXmlFileList类。TXmlManager包含一些其他类似的列表,我只是在其中重复使用名称TItem。但是没有冲突,因为需要添加父类来引用正确的类类型。