2013-08-18 47 views
2

在下面的類中,我成功實現了IEnumerable(T)以遍歷T.在同一個類中,我能夠實現IEnumerable(DLLItem(T ))遍歷DLLItem(T)。兩者都在獨立工作。這可能是一個基本問題。我該怎麼做才能讓迭代器在同一個類中一起工作? 我試過幾種可能性越來越始終編譯器錯誤...在泛型類中實現多個迭代器 - C# - IEnumerable(T)

用的IEnumerable(T)

public class DLL<T> : IEnumerable<T> 
{ 
    ... 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
    public IEnumerator<T> GetEnumerator() 
    { 
    ... 
     yield return ... 
    ... 
    } 
    ... 
} 

用的IEnumerable(DLLItem(T))

public class DLL<T> : IEnumerable<DLLItem<T>> 
{ 
    ... 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
    public IEnumerator<DLLItem<T>> GetEnumerator() 
    { 
    ... 
     yield return ... 
    ... 
    } 
    ... 
} 

在前進,謝謝您的支持...


按照@dasblinkenlight建議的解決方案(請參閱低)


​​
+0

你能表現出使用場景對於這樣的安排? – dasblinkenlight

+5

[是否可以在C#中使用多個迭代器?]](http://stackoverflow.com/questions/1754041/is-multiple-iterators-is-possible-in-c) – lightbricko

回答

1

由於IEnumerable.GetEnumerator()在所有通用的IEnumerable對象之間共享,所以不能在同一個類中實現它們。你必須使其工作兩種選擇:

  • 提供兩個屬性,EnumerableItemEnumerableDllItem,產生不同的迭代器對象,方式在this answer建議,或
  • 進行單獨IEnumerable類 - ItemEnumerable<T>DllItemEnumerable<T>。根本不要在DLL<T>中實現IEnumerable,並提供兩個轉換運算符,從DLL<T>ItemEnumerable<T>DllItemEnumerable<T>。用戶可以通過插入演員來決定使用哪個迭代器。
+0

嗨,我做了你提到的第二種方式,它按預期工作。感謝所有人的回答。 – CSJNL

+0

@CSJNL太好了!如果一切正常並且您不再積極尋找改進的解決方案,請考慮接受答案以表明問題已解決。 – dasblinkenlight

5

這是可能的,但它會是混亂使用。

你必須同時實現IEnumerable<DLLItem<T>>IEnumerable<T>接口:

public class DLL<T> : IEnumerable<DLLItem<T>>, IEnumerable<T> 

GetNumerator方法會發生碰撞,所以你將不得不求助於顯式接口實行,這迫使調用者的對象轉換爲正確的訪問枚舉器之前的接口類型:

var dllItems = ((IEnumerable<DLLItem<T>>)someDll); 
var Ts = ((IEnumerable<T>)someDll); 

我的建議是不要這樣。而是爲一個或兩個枚舉器公開屬性。以Dictionary<TKey, TValue>課爲例。它實施了IEnumerator<KeyValuePair<TKey, TValue>>並且公開了IEnumerable<TValue>類型的Values財產和IEnumerable<TKey>類型的Keys財產。

1

一般喜歡合成而不是繼承。

下面的類很容易ceate和使用:

public class DLL<T> : IEnumerable<T> 
{ 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     throw new NotImplementedException("Need to implement"); 
    } 

    // Compose, not inherit 
    public IEnumerable<DLLItem<T>> DLLItems 
    { 
     get 
     { 
      throw new NotImplementedException("Need to implement"); 
     } 
    } 
}