程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 11.C#迭代器(六章6.1),

11.C#迭代器(六章6.1),

編輯:C#入門知識

11.C#迭代器(六章6.1),


  今天我們說下C#中的迭代器,首先引出一些關於迭代的概念,後面舉出代碼供大家討論。

  迭代器模式是行為模式的一種范例,行為模式是一種簡化對象之間通信的一種設計模式。在.NET中使用IEnumerator和IEnumerable接口及它們的泛型等價物來封裝的,如果一個類型實現了IEnumerable接口,就說明它是可迭代的,調用GetEnumerator方法返回IEnumerator的實現,這是迭代器本身。

  C#1使用foreach語句實現了訪問迭代器的內置支持,foreach語句會被編譯成使用GetEnumerator和MoveNext方法以及Current屬性。C#中迭代器只能向後訪問,而C++中迭代器可以支持前後訪問。

  背景,假設有一個關於學生的隊列,每個學生依次報出自己的名字,Student類如下

 1 class Student
 2 {
 3     public string Name { get; set; }
 4 
 5     public Student(string name)
 6     {
 7         Name = name;
 8     }
 9 
10     public void SayName()
11     {
12         Console.WriteLine(Name);
13     }
14 }

  有一個實現IEnumerable的Queue的泛型類,如下

 1 class Queue<T> : IEnumerable<T> where T : class
 2 {
 3     public List<T> objects = new List<T>();
 4 
 5     public Queue(List<T> list)
 6     {
 7         objects = list;
 8     }
 9 
10     //實現從IEnumerable中的GetEnumerator方法
11     /*
12         個人覺得這個方法在迭代中只會調用一次,不然每次都返回一個新的QueueIterator<T>對象,位置記錄都會重置為-1
13     */
14     public IEnumerator<T> GetEnumerator()
15     {
16         return new QueueIterator<T>(this);  
17     }
18 
19     IEnumerator IEnumerable.GetEnumerator()
20     {
21         throw new NotImplementedException();
22     }
23 }

  使用GetEnumerator方法返回一個迭代器,而迭代器需要實現IEnumerator接口,如下

 

 1 class QueueIterator<T> : IEnumerator<T> where T : class
 2 {
 3     private ConsoleDemo.Chapter6.Queue<T> q = null;
 4 
 5     int startPoint = -1;    //用於保存游標的位置
 6 
 7     public QueueIterator(ConsoleDemo.Chapter6.Queue<T> q)
 8     {
 9         this.q = q;
10     }
11 
12     //返回合適位置上的T類型實例,這個例子中調用提這個自動屬性
13     public T Current
14     {
15         get
16         {
17             if (startPoint==-1 || startPoint==q.objects.Count)
18             {
19                 throw new InvalidOperationException();
20             }
21             int index = startPoint + q.objects.Count;
22             index = index % q.objects.Count;
23             return q.objects[index];
24         }
25     }
26 
27     object IEnumerator.Current
28     {
29         get
30         {
31             if (startPoint == -1 || startPoint == q.objects.Count)
32             {
33                 throw new InvalidOperationException();
34             }
35             int index = startPoint + q.objects.Count;
36             index = index % q.objects.Count;
37             return q.objects[index];
38         }
39     }
40 
41     public void Dispose()
42     {
43         
44     }
45 
46     public bool MoveNext()
47     {
48         if (startPoint != q.objects.Count)
49         {
50             startPoint++;
51         }
52         return startPoint < q.objects.Count;
53     }
54     //當迭代結束後,會調用這個方法,則下一次迭代後重新從第一個位置開始
55     public void Reset()
56     {
57         startPoint = -1;
58     }
59 }

  分別要去實現從IEnumerator中的Current屬性、Dispose方法(有必要的話)、MoveNext方法、Reset方法。使用C#2中的yield語句可以簡化迭代器,再下一篇中再說。

  請斧正。

 

 

 

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved