2013-05-13 33 views
3

我一直在考慮從客戶,看起來像這樣的代碼:我應該定義自定義的枚舉器還是使用內置的枚舉器?

public class Thing 
{ 
    // custom functionality for Thing... 
} 

public class Things : IEnumerable 
{ 
    Thing[] things; 
    internal int Count { get { return things.Length; } } 

    public Thing this[int i] { get { return this.things[i]; } } 

    public IEnumerator GetEnumerator() { return new ThingEnumerator(this); } 

    // custom functionality for Things... 
} 

public class ThingEnumerator : IEnumerator 
{ 
    int i; 
    readonly int count; 
    Things container; 

    public ThingEnumerator(Things container) 
    { 
     i = -1; 
     count = container.Count; 
     this.container = container; 
    } 

    public object Current { get { return this.container[i]; } } 
    public bool MoveNext() { return ++i < count; } 
    public void Reset() { i = -1; } 
} 

什麼我不知道是它是否會好些已經戒掉了ThingEnumerator類,取而代之的Things.GetEnumerator通話一個實現只是委託給arrayGetEnumerator?像這樣:

public IEnumerator GetEnumerator() { return things.GetEnumerator(); } 

保持代碼原樣有什麼好處嗎? (我注意到另一件事是,現有的代碼可以用IEnumerator<Thing>更換IEnumerator得到改善。)

+0

您的直覺是對的。在Generics來到C#之前,這段代碼是舊的。 你可以用 替換GetEnumerator public IEnumerable GoForward(){foreach(var t in things)yield return t; } 爲了迭代你的類,使用Things things = new Things(); foreach(var t in things){...} – graumanoz 2013-05-13 10:28:28

+0

@graumanoz考慮到這一點,這可能是客戶長時間敲響的_old_代碼,如果他們從頭開始寫類似的話,他們會使用更現代的方法。 – TooTone 2013-05-13 10:41:10

+0

TooTone 是的,這是一箇舊的代碼:) 它可以完全取代我以前寫的小方法,順便說一句,現代的方法。 – graumanoz 2013-05-13 10:52:09

回答

2

在一般情況下,有時可能有理由實現自己的枚舉器。你可能需要一些內置的功能,不提供 - 一些驗證,日誌記錄,引發OnAccess類型的事件,可能是一些邏輯來鎖定項目,然後釋放它們以便併發訪問(我見過的代碼是這樣做的最後一個;這很奇怪,我不會推薦它)。

說了這麼多,我在你發佈的例子中看不到類似的東西,所以它似乎沒有增加任何超出IEnumerable提供的值的值。通常,如果有內置的代碼可以實現您想要的功能,請使用它。所有你通過滾動你自己來實現的就是創建更多的代碼來維護。

3

隨着仿製藥,沒有實施IEnumerableIEnumerator自己真的沒有什麼價值。

刪除這些是用泛型集合取代類意味着你有更少的代碼來維護並具有使用已知工作的代碼的優勢。

1

除非你在自定義枚舉器中做了一些真正自定義的事情(比如某種驗證),否則確實沒有任何理由這樣做。

一般情況下,除非有明確的理由,否則請使用標準庫中的可用內容。他們可能會得到更好的測試,並花費更多時間在他們身上,作爲單獨的代碼單元,那麼您可以負擔得起花費,爲什麼重新創建輪子?

在這種情況下,代碼已經存在,但如果您有時間測試的話,代碼可能會更好。 (如果單元測試覆蓋率不錯,那麼這是一個不容小覷的過程。)

您將減少維護開銷,消除潛在錯誤隱患並保持代碼清潔。鮑伯叔叔會感到驕傲。

1

數組枚舉器的功能與您的自定義枚舉器幾乎相同,所以是的,您可以直接返回數組的枚舉數。
在這種情況下,我建議你這樣做,因爲數組枚舉器也執行更多的錯誤檢查,正如你所說的那樣,它只是更簡單。

2

在.NET泛型可用之前,您擁有的代碼看起來像爲.NET 1.0/1.1編寫的代碼 - 當時,實現您自己的集合類(通常來自System.Collections.CollectionBase)有價值,因此索引器屬性可以被鍵入到集合的運行時類型。 但是,除非您使用值類型,裝箱/拆箱是性能限制因素,否則我將繼承CollectionBase,並且不需要重新定義GetEnumerator()Count

但是,現在,我會建議這兩種方法之一:

  1. 如果您需要自定義集合有一些自定義的功能,然後從System.Collections.ObjectModel.Collection<Thing>獲得集合 - 它提供了所有必要的掛鉤您可以控制集合中項目的插入,替換和刪除。

  2. 如果您實際上只需要枚舉某些東西,我會返回一個由List<Thing>支持的標準IList<Thing>