2011-03-02 102 views
7

我有一個類實現IEnumerator<string>。請看下圖:爲什麼我需要IEnumerator.Current在一個實現IEnumerator <T>的類中?

public class MyClass : IEnumerator<string> 
{ 
    public bool MoveNext() 
    { 
     //.... 
    } 

    //Implement other required methods.... 

    //Confusion lies below: 
    public string Current { get { return this.CurrentLine; } } 

    //Why do I need to implement IEnumerator.Current?! In my tests, it's not even called during my iteration 
    object IEnumerator.Current { get { throw new NotImplementedException(); } } 

} 

除了存在兩個IEnumerator<T>接口和IEnumerator接口(其中IEnumerator<T>繼承)上.Current財產,什麼是實現它的點的事實呢?如上所見,它甚至沒有被稱爲。

回答

15

IEnumerator<T> implements IEnumerator,所以在最基本的層面上,你必須履行合同。

具體來說,爲什麼 - 如果有人會發生什麼這樣的:

((IEnumerator)yourInstance).Current 

他們(通常)應該會得到IEnumerator<T>的執行返回的值相同/參考的鬆散類型的副本。所以在大多數情況下,只需返回this.Current並且不用擔心:)

(僅供參考 - 返回this.Current也是一個很好的做法,因爲它遵循DRY和SRP - 讓強類型的Current處理實現細節什麼當前實際的。)

+0

+1給出了一個例子,說明如何在這種情況下調用IEnumerator.Current的實現。 – contactmatt 2011-03-02 19:12:47

3

的原因是,IEnumerator<T>繼承IEnumerator所以當你從IEnumerator<T>繼承你也隱含地從IEnumerator繼承。如果您公佈一個接口,即使您從不打算使用它,也應該爲該接口提供一個實現。

1

編譯器要求您實現所有虛擬,因爲當某個意料之外的程序集在未知的未來某個時間點加載程序集時,它不可能知道哪些程序將被調用。通過從接口繼承,您「簽訂了一份合同」,承諾您將實施其所有成員。編譯器讓你遵守該協議,以便其他程序集將能夠依靠它。

界面功能的目的是讓你的班級能夠告訴任何其他組件,任何地點,任何時間,「這就是你可以要求我做的事情」。如果您想宣傳較小的功能,請定義一個僅提供所需部分功能的新界面,然後實施。

當然,所有這些都是工業強度的東西。這比你現在需要的代碼還要多。但是C#對於做嚴肅的東西是有用的,不僅僅是玩具。

至於兩個不同的,幾乎相同的覆蓋:你必須覆蓋兩個Current屬性,因爲它們本質上是不同的:一個是泛型​​返回T;另一個是非泛型返回對象。您始終可以將String引用視爲對Object的引用,但這並不是雙向的。那麼值類型呢? T並不侷限於一個階級。當然,編譯器可以假設爲你弄明白這一切,並讓你在兩者互換的情況下襬脫困境,但事實並非如此,我不相信它應該如此。如果你想要C++,你知道在哪裏找到它。

相關問題