zoukankan      html  css  js  c++  java
  • 【读书笔记】创建泛型编程类 由链表而深入

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

    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;
  • 相关阅读:
    java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 *&* 解决方法
    一个罕见的MSSQL注入漏洞案例
    工具推荐:ATSCAN,功能强大的Perl脚本扫描器
    突破XSS字符限制执行任意JS代码
    用Nginx分流绕开Github反爬机制
    浅析XSS与XSSI异同
    IE安全系列之——RES Protocol
    跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险
    SQL注入攻击和防御
    SQL 注入,永不过时的黑客技术
  • 原文地址:https://www.cnblogs.com/herbert/p/1740953.html
Copyright © 2011-2022 走看看