枚举器模式(Enumerator pattern)

如何使用枚举器模式(Enumerator pattern):

1、  如果你要实现IEnumerable.GetEnumerator,你也要实现一个GetEnumerator方法的非虚方法版本。你的枚举器类的IEnumerable.GetEnumerator方法应该调用这个非虚方法。如下所示应该返回一个内嵌的枚举器结构:

·                           class MyClass : IEnumerable

·                           {

·                             // non-virtual implementation for your custom collection

·                             public MyEnumerator GetEnumerator() {

·                               return new MyEnumerator(this); // Return nested public struct

·                             }

·                           // IEnumerator implementation

·                             public IEnumerator.GetEnumerator() {

·                               return GetEnumerator();//call the non-interface method

·                             }

·                           }

如果你的类已经显示地提供了非虚的GetEnumerator方法,那么foreach语句就会调用这个非虚的GetEnumerator方法。否则,它会调用IEnumerable.GetEnumerator方法,如果你的类实现了Ienumerable接口。调用一个非虚方法比通过接口调用一个虚方法要更有效。

2、  在枚举器结构中显示的实现IEnumerator.Current属性。.NET的实现类在实现时会使得该属性返回一个System.Object对象,而不是一个强类型的对象。这会存在类型转换开销。通过在你的Current属性中返回一个强类型对象或者精确的值类型而不是System.Object,可以避免类型转换的开销。因为你已经显示地实现了一个非虚地GetEnumerator方法(不是IEnumerable.GetEnumerator方法),CLR能够直接调用Enumerator.Current属性,而不是调用IEnumerator.Current属性,因此可以直接获取所期待的数据,还能避免类型转换和装箱操作的开销。而减少虚方法调用,可以利用方法的内联了。你的实现应该如下:

// Custom property in your class

//call this property to avoid the boxing or casting overhead

Public MyValueType Current {

  MyValueType obj = new MyValueType();

  // the obj fields are populated here

  return obj;       

}

// Explicit member implementation

Object IEnumerator.Current {

get { return Current} // Call the non-interface property to avoid casting

}

注:枚举器模式只有当性能是关键时才适用。

下面的示例代码展示了枚举器模式:

public class  ItemTypeCollection: IEnumerable

{

   public struct MyEnumerator : IEnumerator

   {

      public ItemType Current { get {… } }

      object IEnumerator.Current { get { return Current; } }

      public bool MoveNext() { … }

      …   }

   public MyEnumerator GetEnumerator() { … }

   IEnumerator IEnumerable.GetEnumerator() { … }

   …}

要利用JIT的内联方式,应该避免在你的集合类中使用虚方法,除非你确实需要扩展。同时,在Current属性的实现中返回当前值来允许使用内联,或者使用一个字段。

时间: 2024-09-11 13:20:22

枚举器模式(Enumerator pattern)的相关文章

装饰者模式(Decorator Pattern) 详解

装饰者模式(Decorator Pattern):动态地将责任附加到对象上. 若要扩展功能, 装饰者提供了比继承更有弹性的替代方案. 使用方法: 1. 首先创建组件(Component)父类, 所有类,具体组件(Concrete Component)和装饰者(Decorator)都属于这一类型, 可以进行扩展; 可以是抽象类(abstract class), 也可以是接口(interface); 代码: /** * @time 2014年5月23日 */ package decorator; /

如何使用系统设备枚举器

系统设备枚举器为我们按类型枚举已注册在系统中的Fitler提供了统一的方法.而且它能够区分不同的硬件设备,即便是同一个Filter支持它们.这对那些使用Windows驱动模型和KSProxy Filter的设备来说是非常有用的.系统设备枚举器对它们按不同的设备实例进行对待(译注:虽然它们支持相同Filter). 当我们利用系统设备枚举器查询设备的时候,系统设备枚举器为特定类型的设备(如,音频捕获和视频压缩)生成了一张枚举表(Enumerator).类型枚举器(Category enumerato

乐在其中设计模式(C#) - 建造者模式(Builder Pattern)

原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabcd 介绍 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例 用同样的构建过程创建Sql和Xml的Insert()方法和Get()方法. MessageModel using System;using System.Collections.Generic;using Sy

php中注册器模式类用法实例分析_php技巧

本文实例讲述了php中注册器模式类用法.分享给大家供大家参考,具体如下: 注册器读写类 Registry.class.php <?php /** * 注册器读写类 */ class Registry extends ArrayObject { /** * Registry实例 * * @var object */ private static $_instance = null; /** * 取得Registry实例 * * @note 单件模式 * * @return object */ pu

PHP、Python和Javascript的装饰器模式对比_php实例

修饰模式(Decorator Pattern),又叫装饰者模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式.就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能.装饰模式非常适用于灵活扩展对象的功能,下面是装饰模式的UML图: 例如,有一个技术论坛,用户通过留言进行沟通,由于刚开始论坛里都是熟人,几乎都不需要对留言的内容作出审核,接收留言的页面可以是这样: class SaveMsg(){ private $msg; public funct

状态模式(state pattern) 详解

状态模式(state pattern): 允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类. 建立Context类, 包含多个具体状态(concrete state)类的组合, 根据状态的不同调用具体的方法, state.handle(), 包含set\get方法改变状态. 状态接口(state interface), 包含抽象方法handle(), 具体状态类(concrete state)继承(implement)状态类(state), 实现handle()方法; 具体方法

PHP设计模式之装饰器模式

装饰器设计模式适用于下列工作场合: 需求变化是快速和细小的,而且几乎不影响应用程序的其他部分.() 使用装饰器设计模式设计类的目标是: 不必重写任何已有的功能性代码,而是对某个基于对象应用增量变化. 装饰器设计模式采用这样的构建方式: 在主代码流中应该能够直接插入一个或多个更改或"装饰"目标对象的装饰器,同时不影响其他代码流. <?php        class CD {            public $trackList;                        

状态模式(state pattern) 未使用状态模式详解

状态模式可以控制状态的转换, 未使用设计模式时, 程序会非常繁杂. 具体方法: 1. 状态转换类. /** * @time 2014年7月11日 */ package state; /** * @author C.L.Wang * */ public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; final static int HAS_QUARTER = 2; fin

代理模式(proxy pattern) 未使用代理模式 详解

如果需要监控(monitor)类的某些状态, 则需要编写一个监控类, 并同过监控类进行监控. 但仅仅局限于本地, 如果需要远程监控, 则需要使用代理模式(proxy pattern). 具体方法: 1. 类中需要提供状态信息, 并提供一些get方法, 进行调用. /** * @time 2014年7月11日 */ package proxy; /** * @author C.L.Wang * */ public class GumballMachine { String location; //