【读书笔记】创建泛型编程类 由链表而深入

首先看下一个一般的,非泛型的简化链表类。

using System;

using System.Collections;

using System.Linq;

using System.Text;



// 不要使用System.Collections.Generic命名空间

// 使用System.Collections命名空间

// 否则当继承 IEnumerable类的时候,会有错误发生



/*-----------------------------------------------------------------------

 * 创建泛型类实例

 * 作者: Herbert

 * ----------------------------------------------------------------------

 */



namespace Generic

{

    // 定义一个链表节点 

    // 包含一个节点,节点带有一个value值

    // 同时包含上一个节点和下一个节点的引用

    public class LinkedListNode

    {

        private object value;



        public LinkedListNode(object value)

        {

            this.value = value;

        }



        public object Value

        {

            get

            {

                return value;

            }

        }



        private LinkedListNode next;

        public LinkedListNode Next

        {

            get

            {

                return next;

            }

            internal set

            {

                next = value;

            }

        }



        private LinkedListNode prev;

        public LinkedListNode Prev

        {

            get

            {

                return prev;

            }

            internal set

            {

                prev = value;

            }

        }

    }





    // 定义链表类

    // 链表类包含及诶单类型的first和last字段,标记链表的头尾    

    class LinkedList : IEnumerable

    {

        private LinkedListNode first;

        public LinkedListNode First

        {

            get

            {

                return first;

            }

        }



        private LinkedListNode last;

        public LinkedListNode Last

        {

            get

            {

                return last;

            }

        }



        public LinkedListNode AddLast(object node)

        {

            LinkedListNode newNode = new LinkedListNode(node);



            // AddLast()方法在链表尾添加一个新元素。首先创建创建一个LinkedListNode类型的对象。如果链表是空的,则first和last字段就设置为该新元素

            // 否则就把新元素添加为链表中的最后一个元素

            if (first == null)

            {

                first = newNode;

                last = first;

            }

            else

            {

                last.Next = newNode;

                last = newNode;

            }

            return newNode;

        }



        public IEnumerator GetEnumerator()

        {

            LinkedListNode current = first;

            while (current != null)

            {

                yield return current.Value;

                current = current.Next;

            }

        }

    }





}

 

下面这个是运行的main方法

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace Generic

{

    class Program

    {

        static void Main(string[] args)

        {

            LinkedList list1 = new LinkedList();

            list1.AddLast(2);

            list1.AddLast(4);



            // The casting from string to int is invalid

            //list1.AddLast("6"); 



            foreach (int i in list1)

            {

                Console.WriteLine(i);               

            }



            Console.ReadLine();

        }

    }

}



 

这个里面的//list1.AddLast("6"); 是非法的,因为.NET似乎不能自动把字符串转化为int类型。那样的话,int i in list1这句话就要报错了。

 

下面看泛型后的链表类:

 

using System;

using System.Collections;

using System.Linq;

using System.Text;

using System.Collections.Generic;





/*-----------------------------------------------------------------------

 * 创建泛型类实例

 * 作者: Herbert

 * 网址: http://www.cnblogs.com/herbert

 * ----------------------------------------------------------------------

 */



namespace Generic

{

    // 定义一个链表节点 

    // 包含一个节点,节点带有一个value值

    // 同时包含上一个节点和下一个节点的引用

    public class LinkedListNode<T>

    {

        private T value;



        public LinkedListNode(T value)

        {

            this.value = value;

        }



        public T Value

        {

            get

            {

                return value;

            }

        }



        private LinkedListNode<T> next;

        public LinkedListNode<T> Next

        {

            get

            {

                return next;

            }

            internal set

            {

                next = value;

            }

        }



        private LinkedListNode<T> prev;

        public LinkedListNode<T> Prev

        {

            get

            {

                return prev;

            }

            internal set

            {

                prev = value;

            }

        }

    }





    // 定义链表类

    // 链表类包含及诶单类型的first和last字段,标记链表的头尾    

    public class LinkedList<T> : IEnumerable<T>

    {

        private LinkedListNode<T> first;

        public LinkedListNode<T> First

        {

            get

            {

                return first;

            }

        }



        private LinkedListNode<T> last;

        public LinkedListNode<T> Last

        {

            get

            {

                return last;

            }

        }



        public LinkedListNode<T> AddLast(T node)

        {

            LinkedListNode<T> newNode = new LinkedListNode<T>(node);



            // AddLast()方法在链表尾添加一个新元素。首先创建创建一个LinkedListNode类型的对象。如果链表是空的,则first和last字段就设置为该新元素

            // 否则就把新元素添加为链表中的最后一个元素

            if (first == null)

            {

                first = newNode;

                last = first;

            }

            else

            {

                last.Next = newNode;

                last = newNode;

            }

            return newNode;

        }



        public IEnumerator<T> GetEnumerator()

        {

            LinkedListNode<T> current = first;

            while (current != null)

            {

                yield return current.Value;

                current = current.Next;

            }

        }



        IEnumerator IEnumerable.GetEnumerator()

        {

            return GetEnumerator();

        }        

    }

}



 

运行的Main函数

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace Generic

{

    class Program

    {

        static void Main(string[] args)

        {

            LinkedList<int> list1 = new LinkedList<int>();

            list1.AddLast(1);

            list1.AddLast(3);

            list1.AddLast(5);



            foreach (int i in list1)

            {

                Console.WriteLine(i);               

            }



            Console.ReadLine();

        }

    }

}

 

这里面需要注意IEnumberable 有 泛型和非泛型两者用途,对应的使用的时候,加上适当的命名空间。不然会编译报错。

 

First you have to understand that IEnumberable has both generic and not-generic usage.  That was my problem.  In my code, I included the using System.Collections; namespace and in my code I was doing the following:

 IEnumerable <test_order> orders = db.getOrdersByCustomer(1);

Where test_order was type produced with a Linq to Sql Class and getOrdersByCustomer was a Stored Procedure. 

 

I kept getting the error:

The non-generic type 'System.Collections.IEnumerable' cannot be used with type arguments 

 

Which basically told me my problem, but I was too blind to see it at first.  Since I was just calling the System.Collections.IEnumerable, and not the System.Collections.Generic.IEnumerable, I was not allowing the use of generics; hence the error.  Simple add the following to you code and you will not have this error any longer: 

using System.Collections.Generic;

你可能感兴趣的:(读书笔记)