2011-01-30 36 views
11

繼承是C#中的傳遞關係嗎?C#:傳遞繼承

我問,因爲我不明白爲什麼IList<T>實現ICollection<T>IEnumerable<T>ICollection<T>已經實現IEnumerable<T>

感謝澄清這對我來說。

+0

你可以找到在此類似[問題]一些答案[1] [1]:http://stackoverflow.com/questions/1164757/why-arraylist-implement-ilist-icollection-ienumerable – DesignFirst 2011-01-30 23:22:36

+0

http://stackoverflow.com/questions/4754923/a-question-about-interface-inheritance-in-net/4755044#4755044 – explorer 2011-01-31 04:35:09

回答

4

據我所知,它並沒有真正不管你宣佈IList<T>爲:

public interface IList<T> : ICollection<T>, IEnumerable<T> { ... } 

或簡稱爲:

public interface IList<T> : ICollection<T> { ... } 

想要實現IList<T>將必須實現的任何類所有這些接口,即也是繼承的接口。很明顯,如果你實現了這個接口而沒有實現IEnumerable/IEnumerable<T>接口的GetEnumerator方法,你會得到一個編譯器錯誤;示範的這個「證明」應該足以告訴你「接口繼承」是可傳遞的,的確如此。


旁註1.在一個側面說明(稍偏離主題),認爲你也可以做到以下幾點:

class Base 
{ 
    public void Foo() { ... } 
} 

interface IFoo 
{ 
    void Foo(); 
} 

class Derived : Base, IFoo 
{ } 

Derived並沒有真正實現IFoo;其基類Base提供了方法Foo,但沒有明確實施IFoo本身。

這很好編譯,看起來是因爲接口所需的所有方法都在那裏。 (我會留在那裏,現在就留下確切的技術性討論。)

我提到這個看似不相關的現象的原因是我喜歡用這種方式來考慮接口繼承:您需要實現類聲明中指定的接口所需的所有方法。所以,當我看到

interface ICollection<T> : IEnumerable<T> { ... } 

而不是說,ICollection<T>繼承IEnumerable<T>,我對自己說,ICollection<T>要求他們實施IEnumerable<T>,也都實現類的。」


旁註2。總結這個答案與另一個有點相關的軼事(我保證它會是最後一個):

前段時間我看頻道9上的視頻Inside .NET Rx and IObservable/IObserver in the BCL。正如你現在可能,這兩個新的接口,即將從Rx,被引入到.NET 4的BCL中。一件奇怪的事情是,當你通過observable.Subscribe(observer)訂閱觀察者的觀察者時,你所得到的只是一些匿名的IDisposable。爲什麼?

作爲講話者在視頻解釋,它們可以給所述IDisposable更具描述性的名稱(如ISubscription),通過定義爲類型名稱「別名」如下:

interface ISubscription : IDisposable {} 

然而,他們最後決定反對這一點。他們認爲,一旦ISubscriptionSubscribe方法返回,它將不再明顯,返回的值需要是Dipose d。

所以這是另一個有點問題的「接口繼承」方面,應該記住。

8

它在所有方面都是傳遞性的。可能您用來查看繼承層次結構的工具有一定的顯示方式。儘管您可以明確地實現它,但無法實現接口,因此無法實現它,從而將其從智能感知中隱藏起來。

作爲IList的作者,您可以自由選擇僅從ICollection派生或從ICollection派生和IEnumerable派生。在這種情況下,IEnumerable將是多餘的,並由resharper標記。