本文介绍了实现C#的IEnumerable< T>一LinkedList类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用C#在Linux上使用MonoDevelop的自定义LinkedList类,只是用于测试和学习的缘故。下面的代码编译从来没有,我不知道为什么!它甚至没有告诉我什么是错的。所有的东西它说的是:错误:编译器似乎已经坠毁。详情请查看构建输出垫。当我去检查输出垫,这是没有什么帮助或者:
未处理的异常信息:System.ArgumentException:指定的字段必须在泛型类型定义上声明。
参数名:字段



我能做些什么

 使用系统; 
使用System.Text;
使用System.Collections.Generic;

命名空间的LinkedList
{
公共类myLinkedList< T> :IEnumerable的< T>
{
//列表节点类
// ===============
类的私有ListNode< T>
{
公共数据T;
公共ListNode< T>下一个;

公共ListNode(T D)
{
this.data = D;
this.next = NULL;
}

公共ListNode(T D,ListNode< T> N)
{
this.data = D;
this.next = N;
}
}

// priavte领域
// ===============
私人ListNode< T>面前;
私人诠释的大小;

//构造
// ===========
公共myLinkedList()
{
前= NULL;
大小= 0;
}


//公共方法
// ===============
公共BOOL的isEmpty( )
{
回报(大小== 0);
}

公共BOOL addFront(T元素)
{
前=新ListNode< T>(元素,前);
尺寸++;
返回真;
}

公共BOOL回加(T元素)
{
ListNode< T>电流=前;
,而(current.next!= NULL)
{
电流= current.next;
}

current.next =新ListNode< T>(元);
尺寸++;
返回真;
}

公共重写字符串的ToString()
{
ListNode< T>电流=前;
如果(当前== NULL)
{
返回**** ****空;
}
,否则
{
StringBuilder的SB =新的StringBuilder();
,而(current.next!= NULL)
{
sb.Append(current.data +);
电流= current.next;
}
sb.Append(current.data);

返回sb.ToString();
}
}

//这些使得myLinkedList< T>实现IEnumerable< T>允许$​​ B $ B //在foreach语句中使用的链表。
公众的IEnumerator< T>的GetEnumerator()
{
返回新myLinkedListIterator< T>(正面);
}


类的私有myLinkedListIterator< T> :IEnumerator的< T>
{
私人ListNode< T>当前;
公共虚拟T当前
{
得到
{
返回current.data;
}
}
私人ListNode< T>面前;

公共myLinkedListIterator(ListNode< T&F)的温度
{
前= F;
电流=前;
}

公共BOOL的MoveNext()
{
如果(current.next!= NULL)
{
电流= current.next ;
返回真;
}
,否则
{
返回FALSE;
}
}

公共无效复位()
{
电流=前;
}

公共无效的Dispose()
{
抛出新的异常(不支持的操作);
}
}
}
}


解决方案

您需要添加非通用的API;所以添加到迭代器:

 对象System.Collections.IEnumerator.Current {{返回电流; }} 

和以枚举:

  System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回的GetEnumerator();
}

但!如果你是用手工实现此,你缺少一个窍门。 。一个迭代器块就好办多了。



下面是一个完成执行情况;你不需要写一个枚举器类的所有(你可以删除 myLinkedListIterator< T> 完全):

 公众的IEnumerator< T>的GetEnumerator()
{
VAR节点=前;
,而(节点!= NULL)
{
收益率的回报node.data;
节点= node.next;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回的GetEnumerator();
}


I'm trying to write a custom LinkedList class in C# using monoDevelop on Linux, just for the sake of testing and learning. The following code never compiles, and I have no idea why!! It doesn't even tell me what's wrong. All what it says is: Error: The compiler appears to have crashed. Check the build output pad for details. When I go to check the output pad, it's not helpful either:Unhandled Exception: System.ArgumentException: The specified field must be declared on a generic type definition.Parameter name: field

What can I do?

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");
            }
        }
    }
}
解决方案

You need to add the non-generic APIs; so add to the iterator:

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

and to the enumerable:

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

HOWEVER! If you are implementing this by hand, you are missing a trick. An "iterator block" would be much easier.

The following is a complete implementation; you don't need to write an enumerator class at all (you can remove myLinkedListIterator<T> completely):

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();
}

这篇关于实现C#的IEnumerable&LT; T&GT;一LinkedList类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 21:59