2017-03-16 9 views
2

C#でリンクリストを作成し、確実に動作することを確認するために単体テストカバレッジを持っています。IEnumerable <T>をC#のリンクリストに実装する

リンクされたリストを多数の値と簡単に比較するために、私はCurrentNode.Next!= nullで標準を使用して値を「列挙」し、これらの値をC#リストまたは配列に格納します。

カスタムLinkedListクラスにIEnumerableを実装し、プライベートバッキングコレクションから列挙子を取得することに依存しません。

私のLinkedListクラスのコードは次のとおりです。列挙子は、私が知る限り、開始点と次のメソッドを提供するコレクションクラスから取得するオブジェクトでなければならないので、私は単純なものを見落としているように感じます。私はそれを一般的な方法で動作させることができません。

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace CSharpLibrary.DataStructures.LinkedLists 
{ 
    public class LinkedList<T> : IEnumerable<T> 
    { 
     public Node<T> First { get; private set; } 
     public Node<T> Current { get; set; } 

     public LinkedList(T initialValue) 
     { 
      First = new Node<T>(initialValue); 
     } 

     public void AddNodeToEnd(T value) 
     { 
      Node<T> last = GetLastNode(); 
      last.Next = new Node<T>(value); 
     } 

     public Node<T> GetLastNode() 
     { 
      Node<T> last = First; 
      Node<T> current = First; 
      while (current.Next != null) 
      { 
       last = current.Next; 
       current = current.Next; 
      } 
      return current; 
     } 


     public void Reset() 
     { 
      Current = First; 
     } 

     public IEnumerator<T> GetEnumerator() 
     { 
      throw new NotImplementedException(); 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 
+0

Btwは、親クラスから 'Current'と' Reset() 'を削除しますが、そこには属しません。 – Groo

+0

@Grooありがとう、私は誤ってインターフェイスではなく、リンクリストコレクションクラスでこれらのナビゲーションメソッドを実装していました。 –

答えて

3

カスタムコレクションを作成しているので、あなただけの既存のIEnumerator実装を使用することはできません。

public class LinkedListEnumerator<T> : IEnumerator<T> 
{ 
    public LinkedListEnumerator(LinkedList<T> collection) 
    { 
    } 
    ... 
} 

コンストラクタに列挙するコレクションを渡しています。他の方法でも動作する可能性がありますが、それをそこで取得するのが最も簡単な方法でした。今すぐあなたのIEnumerable<T>実装は次のとおりです。

public IEnumerator<T> GetEnumerator() 
    { 
     return new LinkedListEnumerator<T>(this); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return new LinkedListEnumerator<T>(this); 
    } 

実際IEnumerator実装では、練習として残しました。 IEnumerator<T>を返す方法もyieldキーワードをサポートすることに注意し、ブラッドリーの答えに追加するには

+0

IEnumeratorにはIDisposableインターフェイスに関する1つの質問が含まれています。メモリ内のデータ構造(通常のリンクリストなど)を扱う場合、処分するものは何もありません。 –

+0

@JoshRいいえ、おそらくない – BradleyDotNET

3

public class LinkedList<T> : IEnumerable<T> 
{ 
    ... 

    // this will automagically create the 
    // appropriate class for you 
    public IEnumerator<T> GetEnumerator() 
    { 
     Node<T> current = First; 
     while (current != null) 
     { 
      yield return current.Value; 
      current = current.Next; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     // this will invoke the public generic 
     // version, so there is no recursion 
     return this.GetEnumerator(); 
    } 
} 

あなたは、しかし、彼らはそこに属していない、親クラスからCurrentReset()を削除する必要があります。 GetLastNode()メソッドには2つの重複変数がありますが、そのうちの1つを削除できます。

関連する問題