程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> C# 索引器,實現IEnumerable接口的GetEnumerator()方法,

C# 索引器,實現IEnumerable接口的GetEnumerator()方法,

編輯:關於.NET

C# 索引器,實現IEnumerable接口的GetEnumerator()方法,


當自定義類需要實現索引時,可以在類中實現索引器。

用Table作為例子,Table由多個Row組成,Row由多個Cell組成,

我們需要實現自定義的table[0],row[0]

索引器定義格式為

[修飾符] 數據類型 this[索引類型 index]

以下是代碼

 1     /// <summary>
 2     /// 單元格
 3     /// </summary>
 4     public class Cell
 5     {
 6         /// <summary>
 7         /// Value
 8         /// </summary>
 9         public object Value { get; set; }
10         /// <summary>
11         /// StringValue
12         /// </summary>
13         public string StringValue { get; set; }
14     }
View Code
 1     /// <summary>
 2     /// 行
 3     /// </summary>
 4     public class Row
 5     {
 6         /// <summary>
 7         /// 獲取Row中的Cell數
 8         /// </summary>
 9         public int Length { get; private set; }
10 
11         /// <summary>
12         /// 索引
13         /// </summary>
14         public Cell this[int column]
15         {
16             get
17             {
18                 return this[column];
19             }
20         }
21         /// <summary>
22         /// 行
23         /// </summary>
24         /// <param name="values"></param>
25         public Row(object[] values)
26         {
27             this.Length = values.Length;
28             for (int i = 0; i < this.Length; i++)
29             {
30                 this[i].Value = values[i];
31                 this[i].StringValue = Convert.ToString(values[i]);
32             }
33         }
34         /// <summary>
35         /// 行
36         /// </summary>
37         /// <param name="values"></param>
38         public Row(string[] values)
39         {
40             this.Length = values.Length;
41             for (int i = 0; i < this.Length; i++)
42             {
43                 this[i].Value = values[i];
44                 this[i].StringValue = values[i];
45             }
46         }
47         /// <summary>
48         /// 行
49         /// </summary>
50         /// <param name="values"></param>
51         public Row(int[] values)
52         {
53             this.Length = values.Length;
54             for (int i = 0; i < this.Length; i++)
55             {
56                 this[i].Value = values[i];
57                 this[i].StringValue = values[i].ToString();
58             }
59         }
60     }
View Code

 這時候,Row就可以有自己的索引了,調用如下

 1     public class Test
 2     {
 3         public Test()
 4         {
 5             Row row = new Row(new string[] { "姓名", "性別", "工號" });
 6             if (row.Length > 2)
 7             {
 8                 row[2].StringValue = "學號";
 9             }
10         }
11     }
View Code

 

但是,Row雖然作為一個Cell的集合,卻不能使用foreach進行遍歷。這時候我們需要讓Row繼承IEnumerable接口,並且實現IEnumerable接口的GetEnumerator()方法,

在public class Row : IEnumerable { }中添加如下代碼:

 1         /// <summary>
 2         /// 實現GetEnumerator()方法
 3         /// </summary>
 4         /// <returns></returns>
 5         public IEnumerator GetEnumerator()
 6         { 
 7             for (int i = 0; i < this.Length; i++)
 8             {
 9                 yield return this[i];
10             }
11         }
View Code

這樣,在調用的時候就能使用foreach遍歷了。
Table和Row的關系同理。

 

同樣,我們還可以繼承ICollection<T>, IEnumerable<T>, IList<T>等接口,實現相關接口的方法,就可以打造屬於自己的集合了。

一個完整的Demo如下:

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Diagnostics;
  5 using System.Text;
  6 
  7 namespace MyCollection
  8 {
  9     /// <summary>
 10     /// 表示 Cell 集合
 11     /// </summary>
 12     [DebuggerDisplay("Count = {Count}")]
 13     [Serializable]
 14     public class MyCollection : IEnumerable, IEnumerable<Cell>, ICollection<Cell>, IList<Cell>
 15     {
 16          #region 字段
 17 
 18         /// <summary>
 19         /// 表示空的 Row 圖層的數組。
 20         /// </summary>
 21         private readonly static Row[] emptyArray = null;
 22 
 23         /// <summary>
 24         /// 存儲 Row 圖層的數組。
 25         /// </summary>
 26         private Row[] items = null;
 27 
 28         /// <summary>
 29         /// 當前 Row 圖層的集合的元素數。
 30         /// </summary>
 31         private int count = 0;
 32 
 33         #endregion
 34 
 35         #region 屬性
 36 
 37         /// <summary>
 38         /// 獲取或設置該 Row 的元素總數。
 39         /// </summary>
 40         /// <exception cref="System.ArgumentOutOfRangeException">MyCollection.Capacity 設置為小於 MyCollection.Count 的值。</exception>
 41         private int Capacity
 42         {
 43             get
 44             {
 45                 return this.items.Length;
 46             }
 47             set
 48             {
 49                 if (value != this.items.Length)
 50                 {
 51                     if (value < this.count)
 52                     {
 53                         throw new ArgumentOutOfRangeException("Capacity", "MyCollection.Capacity 設置為小於 MyCollection.Count 的值。");
 54                     }
 55                     if (value > 0)
 56                     {
 57                         Row[] destArray = new Row[value];
 58                         if (this.count > 0)
 59                         {
 60                             Array.Copy(this.items, 0, destArray, 0, this.count);
 61                         }
 62                         this.items = destArray;
 63                     }
 64                     else
 65                     {
 66                         this.items = emptyArray;
 67                     }
 68                 }
 69             }
 70         }
 71 
 72         #endregion
 73 
 74         #region 構造函數
 75         /// <summary>
 76         /// 對 LayerCollection 類進行初始化。
 77         /// </summary>
 78         static MyCollection()
 79         {
 80             emptyArray = new Row[0];
 81         }
 82 
 83         /// <summary>
 84         /// 初始化 HuaXing.ExamOperation.SimulateFlash.LayerCollection 類的新實例。<para/>
 85         /// 表示 Layer 圖層的集合。
 86         /// </summary>
 87         public MyCollection()
 88         {
 89             this.items = emptyArray;
 90         }
 91         #endregion
 92 
 93         #region IList<Row> 成員
 94 
 95         #region IndexOf
 96 
 97         /// <summary>
 98         /// 搜索指定的 Row 對象,並返回整個 MyCollection 中第一個匹配項的從零開始的索引。
 99         /// </summary>
100         /// <param name="item">要在 MyCollection 中定位的 Row 對象。</param>
101         /// <returns>如果在 MyCollection 中找到 item 的第一個匹配項,則為該項的從零開始的索引;否則為-1。</returns>
102         public int IndexOf(Row item)
103         {
104             return Array.IndexOf<Row>(this.items, item, 0, this.count);
105         }
106 
107         /// <summary>
108         /// 搜索指定的 Row 對象,並返回整個 MyCollection 中從指定索引到最後一個元素的元素范圍內第一個匹配項的從零開始的索引。
109         /// </summary>
110         /// <param name="item">要在 MyCollection 中定位的 Row 對象。</param>
111         /// <param name="index">從零開始的搜索的起始索引。</param>
112         /// <returns>如果在 MyCollection 中從 index 到最後一個元素的元素范圍內找到 item 的第一個匹配項,則為該項的從零開始的索引;否則為-1。</returns>
113         /// <exception cref="System.ArgumentOutOfRangeException">index 不在 MyCollection 的有效索引范圍內。</exception>
114         public int IndexOf(Row item, int index)
115         {
116             if (index < 0 || index > this.count)
117             {
118                 throw new ArgumentOutOfRangeException("index", "index 不在 MyCollection 的有效索引范圍內。");
119             }
120             return Array.IndexOf<Row>(this.items, item, index, this.count - index);
121         }
122 
123         /// <summary>
124         /// 搜索指定的 Row 對象,並返回整個 MyCollection 中從指定的索引開始並包含指定的元素數的元素范圍內第一個匹配項的從零開始的索引。
125         /// </summary>
126         /// <param name="item">要在 MyCollection 中定位的 Row 對象。</param>
127         /// <param name="index">從零開始的搜索的起始索引。</param>
128         /// <param name="count">要搜索的部分中的元素數。</param>
129         /// <returns>如果在 MyCollection 中從 index 開始並包含 count 個元素的元素范圍內找到 item 的第一個匹配項,則為該項的從零開始的索引;否則為-1。</returns>
130         /// <exception cref="System.ArgumentOutOfRangeException">index 不在 MyCollection 的有效索引范圍內 或 count 小於 0  或 index 和 count 未指定 MyCollection 中的有效部分。</exception>
131         public int IndexOf(Row item, int index, int count)
132         {
133             if (index < 0 || index > this.count)
134             {
135                 throw new ArgumentOutOfRangeException("index", "index 不在 MyCollection 的有效索引范圍內。");
136             }
137             if ((count < 0) || (index > (this.count - count)))
138             {
139                 throw new ArgumentOutOfRangeException("count", "count 小於 0 或 index 和 count 未指定 MyCollection 中的有效部分。");
140             }
141             return Array.IndexOf<Row>(this.items, item, index, count);
142         }
143 
144         #endregion
145 
146         #region Insert
147 
148         /// <summary>
149         /// 將 Row 對象插入 MyCollection 的指定索引處。
150         /// </summary>
151         /// <param name="index">從零開始的索引,應在該位置插入 item。</param>
152         /// <param name="item">要插入的 Row 對象。</param>
153         /// <exception cref="System.ArgumentOutOfRangeException">index 小於 0 或 index 大於 MyCollection.Count。</exception>
154         public void Insert(int index, Row item)
155         {
156             if (index < 0 || index > this.count)
157             {
158                 throw new ArgumentOutOfRangeException("index", "index 小於 0 或 index 大於 MyCollection.Count。");
159             }
160             if (this.count == this.items.Length)
161             {
162                 this.EnsureCapacity(this.count + 1);
163             }
164             if (index < this.count)
165             {
166                 Array.Copy(this.items, index, this.items, index + 1, this.count - index);
167             }
168             this.items[index] = item;
169             this.count++;
170         }
171 
172         #endregion
173 
174         #region RemoveAt
175 
176         /// <summary>
177         /// 移除 MyCollection 的指定索引處的 Row 對象。
178         /// </summary>
179         /// <param name="index">要移除的 Row 對象的從零開始的索引。</param>
180         /// <exception cref="System.ArgumentOutOfRangeException">index 小於 0 或 index 等於或大於 MyCollection.Count。</exception>
181         public void RemoveAt(int index)
182         {
183             if (index < 0 || index >= this.count)
184             {
185                 throw new ArgumentOutOfRangeException("index", "index 小於 0 或 index 等於或大於 MyCollection.Count。");
186             }
187             this.count--;
188             if (index < this.count)
189             {
190                 Array.Copy(this.items, index + 1, this.items, index, this.count - index);
191             }
192             this.items[this.count] = default(Row);
193         }
194 
195         #endregion
196 
197         #region Item[Int32]
198 
199         /// <summary>
200         /// 獲取或設置指定索引處的 Row 對象。
201         /// </summary>
202         /// <param name="index">要獲取或設置的 Row 對象從零開始的索引。</param>
203         /// <returns>指定索引處的 Row 對象。</returns>
204         /// <exception cref="System.ArgumentOutOfRangeException">index 小於 0 或 index 等於或大於 MyCollection.Count。</exception>
205         public Row this[int index]
206         {
207             get
208             {
209                 if (index < 0 && index >= this.count)
210                 {
211                     throw new ArgumentOutOfRangeException("index", "index 小於 0 或 index 等於或大於 MyCollection.Count。");
212                 }
213                 else
214                 {
215                     return this.items[index];
216                 }
217             }
218             set
219             {
220                 if (index < 0 && index >= this.count)
221                 {
222                     throw new ArgumentOutOfRangeException("index", "index 小於 0 或 index 等於或大於 MyCollection.Count。");
223                 }
224                 else
225                 {
226                     this.items[index] = value;
227                 }
228             }
229         }
230 
231         #endregion
232 
233         #endregion
234 
235         #region ICollection<Row> 成員
236 
237         #region Add
238 
239         /// <summary>
240         /// 將 Row 對象,添加到 MyCollection 的結尾處。
241         /// </summary>
242         /// <param name="item">要添加到 MyCollection 的末尾處的 Row 對象。</param>
243         public void Add(Row item)
244         {
245             if (this.count == this.items.Length)
246             {
247                 this.EnsureCapacity(this.count + 1);
248             }
249             this.items[this.count++] = item;
250         }
251 
252         #endregion
253 
254         #region Clear
255 
256         /// <summary>
257         /// 從 MyCollection 集合中移除所有元素。
258         /// </summary>
259         public void Clear()
260         {
261             if (this.count > 0)
262             {
263                 Array.Clear(this.items, 0, this.count);
264                 this.count = 0;
265             }
266         }
267 
268         #endregion
269 
270         #region Contains
271 
272         /// <summary>
273         /// 確定 MyCollection 集合中,是否包含特定值。
274         /// </summary>
275         /// <param name="value">要在 MyCollection 集合中查找的 Row。</param>
276         /// <returns>如果在 MyCollection 集合中找到 Row,則為true;否則為false。</returns>
277         public bool Contains(Row value)
278         {
279             if (value == null)
280             {
281                 for (int j = 0; j < this.count; j++)
282                 {
283                     if (this.items[j] == null)
284                     {
285                         return true;
286                     }
287                 }
288                 return false;
289             }
290             EqualityComparer<Row> comparer = EqualityComparer<Row>.Default;
291             for (int i = 0; i < this.count; i++)
292             {
293                 if (comparer.Equals(this.items[i], value))
294                 {
295                     return true;
296                 }
297             }
298             return false;
299         }
300 
301         #endregion
302 
303         #region CopyTo
304 
305         /// <summary>
306         /// 將整個 MyCollection 復制到一維數組中,從目標數組的開頭開始放置。
307         /// </summary>
308         /// <param name="array">作為從 MyCollection 復制的元素的目標位置的一維數組。</param>
309         /// <exception cref="System.ArgumentException">源 MyCollection 中的元素數大於目標 array 可包含的元素數。</exception>
310         /// <exception cref="System.ArgumentNullException">array 為 null。</exception>
311         public void CopyTo(Row[] array)
312         {
313             this.CopyTo(array, 0);
314         }
315 
316         /// <summary>
317         /// 將整個 MyCollection 復制到一維數組中,從目標數組的指定索引位置開始放置。
318         /// </summary>
319         /// <param name="array">作為從 MyCollection 復制的元素的目標位置的一維數組。</param>
320         /// <param name="arrayIndex">array 中從零開始的索引,在此處開始復制。</param>
321         /// <exception cref="System.ArgumentException">arrayIndex 等於或大於 array 的長度 或 源 MyCollection 中的元素數目大於從 arrayIndex 到目標 array 末尾之間的可用空間。</exception>
322         /// <exception cref="System.ArgumentNullException">array 為 null。</exception>
323         /// <exception cref="System.ArgumentOutOfRangeException">arrayIndex 小於 0。</exception>
324         public void CopyTo(Row[] array, int arrayIndex)
325         {
326             Array.Copy(this.items, 0, array, arrayIndex, this.count);
327         }
328 
329         /// <summary>
330         /// 將一定范圍的元素從 MyCollection 復制到一維數組中,從目標數組的指定索引位置開始放置。
331         /// </summary>
332         /// <param name="index">源 MyCollection 中復制開始位置的從零開始的索引。</param>
333         /// <param name="array">作為從 MyCollection 復制的元素的目標位置的一維數組。</param>
334         /// <param name="arrayIndex">array 中從零開始的索引,在此處開始復制。</param>
335         /// <param name="count">要復制的元素數。</param>
336         /// <exception cref="System.ArgumentException">index 等於或大於源 MyCollection 的 MyCollection.Count 或 arrayIndex 等於或大於 array 的長度 或 從 index 到源 MyCollection 的末尾的元素數大於從 arrayIndex 到目標 array 的末尾的可用空間。</exception>
337         /// <exception cref="System.ArgumentNullException">array 為 null。</exception>
338         /// <exception cref="System.ArgumentOutOfRangeException">index 小於 0 或 arrayIndex 小於 0 或 count 小於 0。</exception>
339         public void CopyTo(int index, Row[] array, int arrayIndex, int count)
340         {
341             if ((this.count - index) < count)
342             {
343                 throw new ArgumentException("index 等於或大於源 MyCollection 的 MyCollection.Count 或 arrayIndex 等於或大於 array 的長度 或 從 index 到源 MyCollection 的末尾的元素數大於從 arrayIndex 到目標 array 的末尾的可用空間。", "index");
344             }
345             Array.Copy(this.items, index, array, arrayIndex, count);
346         }
347 
348         #endregion
349 
350         #region Count
351 
352         /// <summary>
353         /// 獲取當前 Row 集合的元素數。
354         /// </summary>
355         public int Count
356         {
357             get
358             {
359                 return this.count;
360             }
361         }
362 
363         #endregion
364 
365         #region IsReadOnly
366 
367         /// <summary>
368         /// 獲取一個值,該值指示 MyCollection 是否為只讀。
369         /// </summary>
370         bool ICollection<Row>.IsReadOnly
371         {
372             get
373             {
374                 return false;
375             }
376         }
377 
378         #endregion
379 
380         #region Remove
381 
382         /// <summary>
383         /// 從 MyCollection 中移除特定 Row 對象的第一個匹配項。
384         /// </summary>
385         /// <param name="item">要從 MyCollection 中移除的 Row 對象。</param>
386         /// <returns>如果成功移除 item,則為 true;否則為 false。如果在 MyCollection 中沒有找到 item,該方法也會返回 false。</returns>
387         public bool Remove(Row item)
388         {
389             int index = this.IndexOf(item);
390             if (index >= 0)
391             {
392                 this.RemoveAt(index);
393                 return true;
394             }
395             return false;
396         }
397 
398         #endregion
399 
400         #endregion
401 
402         #region IEnumerable<Row> 成員
403 
404         public IEnumerator<Row> GetEnumerator()
405         {
406             for (int index = 0; index < this.count; index++)
407             {
408                 yield return this.items[index];
409             }
410         }
411 
412         #endregion
413 
414         #region IEnumerable 成員
415 
416         IEnumerator IEnumerable.GetEnumerator()
417         {
418             for (int index = 0; index < this.count; index++)
419             {
420                 yield return this.items[index];
421             }
422         }
423 
424         #endregion
425 
426         #region 輔助方法
427 
428         /// <summary>
429         /// 確保當前集合的容量,不小於指定的值。
430         /// </summary>
431         /// <param name="min">指定一個值,此方法會確保當前集合的容量不小於此值。</param>
432         private void EnsureCapacity(int min)
433         {
434             if (this.items.Length < min)
435             {
436                 int num = this.items.Length;
437                 if (num < min)
438                 {
439                     num = min;
440                 }
441                 this.Capacity = num;
442             }
443         }
444         #endregion
445     }
446 }
View Code

 

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