【读书笔记】创建泛型编程类 由链表而深入
首先看下一个一般的,非泛型的简化链表类。
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;
浙公网安备 33010602011771号