小談IEnumerable和IEnumerator接口

IEnumerable
  (1) 成員: IEnumerator GetEnumerator()
     1) 可以定義一個函數用於迭代, 即foreach...in...結構中
     eg: public static IEnumerable Get()
         {
            for (int i = 0; i < 10; i++)
           {
              yield return i;
           }
         }
        
         在Main()函數中就可以這樣使用:
        
         foreach (int i in Get())
         {
          //TODO
         }
     2) 可以在類或結構中定義成員函數用於迭代對象或結構中的數據,可以定義多個
     eg: class Test
     {
     public Test()
     {}
   
    public IEnumerable Get1()
    {
    for (int i = 0; i < 10; i++)
    {
     yield return i;
    }
    }
   
    public IEnumerable Get2()
    {
    for (char ch = 'a'; ch <= 'z'; ch++)
    {
     yield return ch;
    }
    }
   }
  
   在Main()函數中就可以這樣使用:
  
   Test test = new Test();
  
   foreach (int i in test.Get1())
   {
   //TODO
   }
  
   foreach (char ch in test.Get2())
   {
   //TODO
   }
  
  3) 當類或結構繼承IEnumerable接口時該類就要實現IEnumerator GetEnumerator()方法, 還可以定義迭代屬性
  eg: class Test : IEnumerable
   {
    public Test()
    {}
   
    public IEnumerator GetEnumerator()
    {
     for (int i = 0; i < 10; i++)
     {
      yield return i;
     }
    }
   
    public IEnumerable BigToSmall
    {
     get
     {
      for (int i = 9; i >= 0; i--)
      {
       yield return i;
      }
     }
    }
   
    public IEnumerable SmallToBig
    {
     get
     {
      return this;
     }
    }
   }
  
   在Main()函數中可以這樣使用:
  
   Test test = new Test();
  
   foreach (int i in test) //這種迭代只有在Test繼承實現了IEnumerable接口後才能使用
   {
    //TODO
   }
  
   foreach (int i in test.BigToSmall)
   {
    //TODO
   }
  
   foreach (int i in test.SmallToBig)//這裡其實調用的還是Test類中實現的IEnumerable接口的IEnumerator GetEnumerator()方法, 因為SmallToBig返回的就是調用該屬性的對象本身
   {
    //TODO
   }

 

IEnumerator: 枚舉數沒有對集合的獨占訪問權; 因此,枚舉通過集合在本質上不是一個線程安全的過程. 即使一個集合已進行同步, 其他線程仍可以修改該集合, 這將導致
    枚舉數引發異常. 若要在枚舉過程中保證線程安全, 可以在整個枚舉過程中鎖定集合, 或者捕捉由於其他線程進行的更改而引發的異常.

  1. 成員:
 
    1) object Current //獲取當前的枚舉數, 最初Current停留在第一個枚舉數之前, 不能使用, 當調用一次MoveNext()後才指向第一個枚舉數
       {
           get { }
       }
      
    2) bool MoveNext(): 使Current指向下一個對象(如果存在的話), 存在下一個則返回true, 不存在則返回false
   
    3) void Reset(): 重置Current, 使其恢復最初的狀態, 停留在第一個枚舉數之前

  2. 使用yield return來模擬實現IEnumerator接口: 注意Current中存儲的都是object類型的對象, 要先進行類型轉換再處理
 
    1) 可以定義一個返回IEnumerator類型的函數, 就實現了IEnumerator接口中的Current屬性,MoveNext()和Reset()方法
 eg: public static Gets()
     {
   for (int i = 0; i < 10; i++)
   {
    yield return i;
   }
     }
    
     在Main()函數中就可以這樣調用:
    
     IEnumerator test = Gets();
    
     while (test.MoveNext())
     {
   //TODO
     }
 
    2) 可以在類或對象中使用yield return 來返回一個IEnumerator類型的變量
    eg: public Test
        {
   public Test()
   {}
   
   public IEnumerator BigToSmall
   {
    get
    {
     for (int i = 9; i >= 0; i--)
     {
      yield return i;
     }
    }
   }
   
   public IEnumerator SmallToBig()
   {
    for (int i = 0; i < 10; i++)
    {
     yield return i;
    }
   }
        }
       
        在Main()函數中就可以這樣使用:
       
        Test test = new Test();
       
        while (test.BigToSmall.MoveNext())
        {
   //TODO
        }
       
        while (test.SmallToBig().MoveNext())
        {
   //TODO
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值