3

テストと学習のために、LinuxでmonoDevelopを使用してC#でカスタムLinkedListクラスを作成しようとしています。次のコードはコンパイルされません。理由はわかりません。何が悪いのかさえ教えてくれません。エラー:コンパイラがクラッシュしたようです。詳細については、ビルド出力パッドを確認してください。出力パッドを確認するときも役に立ちません。未処理の例外:System.ArgumentException:指定されたフィールドはジェネリック型定義で宣言する必要があります。パラメータ名:フィールド

私に何ができる?

using System;
using System.Text;
using System.Collections.Generic;

namespace LinkedList
{
    public class myLinkedList<T> : IEnumerable<T>
    {
        //List Node class
        //===============
        private class ListNode<T>
        {
            public T data;
            public ListNode<T> next;

            public ListNode(T d)
            {
                this.data = d;
                this.next = null;
            }

            public ListNode(T d, ListNode<T> n)
            {
                this.data = d;
                this.next = n;
            }
        }

        //priavte fields
        //===============
        private ListNode<T> front;
        private int size;

        //Constructor
        //===========
        public myLinkedList ()
        {
            front = null;
            size = 0;
        }


        //public methods
        //===============
        public bool isEmpty()
        {
            return (size == 0);
        }

        public bool addFront(T element)
        {
            front = new ListNode<T>(element, front);
            size++;
            return true;
        }

        public bool addBack(T element)
        {
            ListNode<T> current = front;
            while (current.next != null)
            {
                current = current.next;
            }

            current.next = new ListNode<T>(element);
            size++;
            return true;
        }

        public override string ToString()
        {
            ListNode<T> current = front;
            if(current == null)
            {
                return "**** Empty ****";
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                while (current.next != null)
                {
                    sb.Append(current.data + ", ");
                    current = current.next;
                }
                sb.Append(current.data);

                return sb.ToString();
            }
        }

        // These make myLinkedList<T> implement IEnumerable<T> allowing
        // a LinkedList to be used in a foreach statement.
        public IEnumerator<T> GetEnumerator()
        {
            return new myLinkedListIterator<T>(front);
        }


        private class myLinkedListIterator<T> : IEnumerator<T>
        {
            private ListNode<T> current;
            public virtual T Current
            {
                get
                {
                    return current.data;
                }
            }
            private ListNode<T> front;

            public myLinkedListIterator(ListNode<T> f)
            {
                front = f;
                current = front;
            }

            public bool MoveNext()
            {
                if(current.next != null)
                {
                    current = current.next;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            public void Reset()
            {
                current = front;
            }

            public void Dispose()
            {
                throw new Exception("Unsupported Operation");
            }
        }
    }
}
4

2 に答える 2

14

非汎用APIを追加する必要があります。したがって、イテレータに追加します。

object System.Collections.IEnumerator.Current { get { return Current;  } }

そして列挙可能なものに:

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

でも!これを手作業で実装している場合、トリックが欠けています。「イテレータブロック」の方がはるかに簡単です。

以下は完全な実装です。列挙子クラスを作成する必要はまったくありません(完全に削除できますmyLinkedListIterator<T>)。

public IEnumerator<T> GetEnumerator()
{
    var node = front;
    while(node != null)
    {
        yield return node.data;
        node = node.next;
    }
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}
于 2012-08-22T08:40:44.843 に答える
5

貼り付けたコードを試してみると、ビルドしようとすると2つのエラーが発生します。

myLinkedList'は、インターフェイスメンバー' System.Collections.IEnumerable.GetEnumerator()'を実装していません。'.myLinkedList.GetEnumerator()'は、一致する戻りタイプ'System.Collections.IEnumerator'がないため、'System.Collections.IEnumerable.GetEnumerator()'を実装できません。

解決策は、最初のクラスで以下を実装することです。

IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

そして2番目のエラーは:

myLinkedList.myLinkedListIterator'は、インターフェイスメンバー'System.Collections.IEnumerator.Current'を実装していません。'JonasApplication.myLinkedList.myLinkedListIterator.Current'は、'object'の一致する戻りタイプがないため、'System.Collections.IEnumerator.Current'を実装できません。

2番目の解決策は、2番目のクラスに実装する次のようなものである可能性があります。

object IEnumerator.Current {get {return Current; }}

于 2012-08-22T08:41:25.003 に答える