/*
 每个List对象都封装了一个ListNode对象链表。ListNode类由两个成员变量(data和next)组成。
 成员data可以引用任何对象。成员next保存对链表下一个ListNode对象的引用。List分别用属性
 Data和Next访问ListNode的两个成员变量。
 List类包含私有成员 firstNode和lastNode。构造函数将两个引用都初始化为null.InserAtFront、
 InsertAtBack、RemoveFromFront和RemoveFromBack是List类的主要方法。这些方法被用于多线程
 程序时,要用一个lock块来保证List类的多线程安全。IsEmpty是一个谓词方法,用于判断链表是
 否为空。Print方法显示了链表的内容。IsEmpty和Print方法都使用了lock块,以确保链表的状态
 能在这两个方法执行任务时保持不变。
 */
using System;namespace test
{
public class ListNode
{
private object data;
private ListNode next; //constractor to create ListNode that refers to dataValue
//and is last node in list
public ListNode( object dataValue)
: this(dataValue,null)
{
}
//constractor to create ListNode that refers to dataValue
//and refers to next ListNode in List
public ListNode( object dataValue,ListNode nextNode)
{
data = dataValue;
next = nextNode;
}
//property Next
public ListNode Next
{
get
{
return next;
}
set
{
next = value;
}
} //property Data
public object Data
{
get
{
return data;
}
}

}//End class ListNode //class List definition
public class List
{
public ListNode firstNode;
public ListNode lastNode;
private string name;//string to display //construct empty List with specified name
public List( string listName)
{
name = listName;
firstNode = lastNode = null;
}
//constract empty List with "list" as its name
public List() : this ("list")
{
} //Insert object at front of list.If List is empty,
//firstNode and last Node will refer to same onject.
//Otherwise,firstNode refers to new node.
public void InsertAtFront(object insertItem)
{
lock( this )
{
if ( IsEmpty() )
firstNode = lastNode = 
new ListNode( insertItem );
else
firstNode =
new ListNode( insertItem,firstNode);
}
}
//Insert object at end of List.If List is empty,
//firstNode and lastNode will refer to same object.
//Otherwise,lastNode's Next property refers to new node.
public void InsertAtBack( object insertItem )
{
lock( this )
{
if ( IsEmpty())
firstNode = lastNode = 
new ListNode( insertItem );
else
lastNode = lastNode.Next =
new ListNode( insertItem );
}
} //remove first node from list
public object RemoveFromFront()
{
lock ( this )
{
if ( IsEmpty() )
throw new EmptyListException( name );
object removeItem = firstNode.Data;//retrieve data //reset firstNode and lastNode references
if ( firstNode == lastNode)
firstNode = lastNode = null;
else
firstNode = firstNode.Next;
return removeItem;//return removed data
}
}
//remove last node from List
public object RemoveFromBack()
{
lock ( this )
{
if ( IsEmpty())
throw new EmptyListException ( name );
object removeItem = lastNode.Data;//retrieve data //reset firstNode and lastNode references
if ( firstNode == lastNode )
firstNode = lastNode = null;
else
{
ListNode current = firstNode; //loop while current node is not lastNode
while ( current.Next != lastNode)
current = current.Next;//move to next node //current is new lastNode
lastNode = current;
current.Next = null;
} return removeItem;//return removed data
}
} //return true if List is empty
public bool IsEmpty()
{
lock ( this )
{
return firstNode == null;
}
}
//output List contents
virtual public void Print()
{
lock ( this )
{
if ( IsEmpty() )
{
Console.WriteLine("Empty"+name);
return;
} Console.Write("The" + name + " is: ");
ListNode current = firstNode; //Output current node data while not at end of list
while (current != null)
{
Console.Write( current.Data+" ");
current = current.Next;
}
Console.WriteLine("\n");
}
}
}//end class List

//class EmptyListException definition
public class EmptyListException : ApplicationException
{
public EmptyListException( string name)
: base ("The" + name + "is empty.")
{
}
}//end
}//end namespace