枚舉器模式(Enumerator pattern)
2024-07-21 02:16:04
供稿:網友
 
如何使用枚舉器模式(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屬性的實現中返回當前值來允許使用內聯,或者使用一個字段。