2011-02-11 83 views
37

IEnumerableIEnumerable<T>有什麼區別?IEnumerable和IEnumerable之間的區別<T>?

我見過很多實現這兩個接口的框架類,因此我想知道通過實現這兩個接口能獲得什麼好處?

請看看他們是如何被定義:

public interface IEnumerable 
{ 
    [DispId(-4)] 
    IEnumerator GetEnumerator(); 
} 
public interface IEnumerable<T> : IEnumerable 
{ 
    IEnumerator<T> GetEnumerator(); 
} 

正如我們看到的,IEnumerable<T>IEnumerable派生,這意味着無論IEnumerable有,IEnumerable<T>繼承,那麼爲什麼我們實施的兩個,而不是僅僅IEnumerable<T> ?執行IEnumerable<T>還不夠?

同樣,也有其他類似的對:

  • IListIList<T>
  • ICollectionICollection<T>

我想知道這些孩子的。

回答

48

基本上,非通用接口在.NET 1.0和1.1中排在第一位。然後,當.NET 2.0推出時,泛型等價物出來了。基本上你同時實現,你必須使用顯式接口 - 生命本來是一個簡單了很多,如果仿製藥已經使它成爲.NET 1.0 :)

在落實方面「唯一」的IEnumerable<T>而不是兩個因爲兩者都定義了無參數GetEnumerator方法。作爲IEnumerator<T>延伸IEnumerator過,它通常是這樣的:

public IEnumerator<T> GetEnumerator() 
{ 
    // Return real iterator 
} 

// Explicit implementation of nongeneric interface 
IEnumerator IEnumerable.GetEnumerator() 
{ 
    // Delegate to the generic implementation 
    return GetEnumerator(); 
} 

在另一方面,在C#2中引入(與yield return等),你很少需要完全採用手工實現這些東西,幸運的迭代塊。您可能需要編寫類似上面的內容,然後在GetEnumerator方法中使用yield return

注意IList<T>延長IListICollection<T>延伸ICollection。這是因爲它的類型安全性較低......而任何泛型迭代器都可以看作是非泛型迭代器,因爲(可能裝箱)將任何值轉換爲object,IListICollection允許值爲添加到採集;向IList<int>添加(比如說)一個字符串是沒有意義的。

編輯:我們需要IEnumerable<T>的原因是,我們可以以類型安全的方式進行迭代,並傳播這些信息。如果我向您返回IEnumerable<string>,那麼您知道可以安全地假定從它返回的所有內容都是字符串引用或null。使用IEnumerable時,我們必須有效地投射(通常隱含在foreach語句中)從該序列返回的每個元素,因爲IEnumeratorCurrent屬性只是object類型。至於我們爲什麼仍然需要IEnumerable - 因爲舊的接口基本上永遠不會消失。使用它的現有代碼太多了。

這本來是可能的IEnumerable<T>不延長IEnumerable,但後來想利用一個IEnumerable<T>的任何代碼不能調用到的方法接受IEnumerable - 並且有很多的這樣的,從.NET 1.1的方法和1.0。

+12

+1如果泛型將它變成.NET 1.0,生活本來會簡單得多...... – Oded

+0

@Jon:問題是:爲什麼我們甚至需要在實現IEnumerable時實現IEnumerable' IEnumerable ' , 或相反亦然? – Nawaz

+0

@Nawaz:我編輯了我的答案。您對泛型爲什麼是好事的想法有多舒服? –

5

一個返回Object類型的對象,另外一個返回類型T的對象

2

至於爲什麼你看到的類定義這兩個,但足以IEnumerable的< T>實現IEnumerable,它不是必要的,但就是很不錯在自我記錄中有時列出子接口。考慮

interface IA { } 
interface IB : IA { } 

class A : IB {} // legal, IB implements IA 

class B : IA, IB {} // also legal, possible more clear on intent 
1

雖然通過循環迭代IEnumerator維護狀態。 它記住了光標位置,IEnumerable沒有。

相關問題