using System; using System.Collections.Generic; public class MyList<T> //type parameter T in angle brackets { private Node head; // The nested type is also generic on T. private class Node { private Node next; //T as private member data type: private T data; //T used in non-generic constructor: public Node(T t) { next = null; data = t; } public Node Next { get { return next; } set { next = value; } } //T as return type of property: public T Data { get { return data; } set { data = value; } } } public MyList() { head = null; } //T as method parameter type: public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } }
class Program { static void Main(string[] args) { //int is the type argument. MyList<int> list = new MyList<int>(); for (int x = 0; x < 10; x++) list.AddHead(x); foreach (int i in list) { Console.WriteLine(i); } Console.WriteLine("Done"); } }
//The .NET Framework 1.1 way of creating a list ArrayList list1 = new ArrayList(); list1.Add(3); list1.Add(105); //... ArrayList list2 = new ArrayList(); list2.Add(「It is raining in Redmond.」); list2.Add("It is snowing in the mountains."); //...
ArrayList list = new ArrayList(); //Okay. list.Add(3); //Okay, but did you really want to do this? list.Add(.「It is raining in Redmond.」); int t = 0; //This causes an InvalidCastException to be returned. foreach(int x in list) { t += x; }
The .NET Framework 2.0 way of creating a list List<int> list1 = new List<int>(); //No boxing, no casting: list1.Add(3); //Compile-time error: list1.Add("It is raining in Redmond.");
MyList<MyClass> list1 = new MyList<MyClass>(); MyList<float> list2 = new MyList<float>(); MyList<SomeStruct> list3 = new MyList<SomeStruct>();
public class Employee { public class Employee { private string name; private int id; public Employee(string s, int i) { name = s; id = i; } public string Name { get { return name; } set { name = value; } } public int ID { get { return id; } set { id = value; } } } } class MyList<T> where T: Employee { //Rest of class as before. public T FindFirstOccurrence(string s) { T t = null; Reset(); while (HasItems()) { if (current != null) { //The constraint enables this: if (current.Data.Name == s) { t = current.Data; break; } else { current = current.Next; } } //end if } // end while return t; } }
約束
|
描述
|
where T: struct
|
類型參數必須爲值類型。
|
where T : class
|
類型參數必須爲類型。
|
where T : new()
|
類型參數必須有一個公有、無參的構造函數。當於其它約束聯合使用時,new()約束必須放在最後。
|
where T : <base class name>
|
類型參數必須是指定的基類型或是派生自指定的基類型。
|
where T : <interface name>
|
類型參數必須是指定的接口或是指定接口的實現。能夠指定多個接口約束。接口約束也能夠是泛型的。
|
class List<T> { //... void Add<U>(List<U> items) where U:T {…} }
// concrete type class Node<T> : BaseNode //closed constructed type class Node<T> : BaseNode<int> //open constructed type class Node<T> : BaseNode<T>
//No error. class Node : BaseNode<int> //Generates an error. class Node : BaseNode<T>
//Generates an error. class Node<T> : BaseNode<T, U> {…} //Okay. class Node<T> : BaseNode<T, int>{…}
using System; using System.Collections.Generic; //Type parameter T in angle brackets. public class MyList<T> { protected Node head; protected Node current = null; // Nested type is also generic on T protected class Node { public Node next; //T as private member datatype. private T data; //T used in non-generic constructor. public Node(T t) { next = null; data = t; } public Node Next { get { return next; } set { next = value; } } //T as return type of property. public T Data { get { return data; } set { data = value; } } } public MyList() { head = null; } //T as method parameter type. public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } // Implement IEnumerator<T> to enable foreach // iteration of our list. Note that in C# 2.0 // you are not required to implment Current and // GetNext. The compiler does that for you. public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } } public class SortedList<T> : MyList<T> where T : IComparable<T> { // A simple, unoptimized sort algorithm that // orders list elements from lowest to highest: public void BubbleSort() { if (null == head || null == head.Next) return; bool swapped; do { Node previous = null; Node current = head; swapped = false; while (current.next != null) { // Because we need to call this method, the SortedList // class is constrained on IEnumerable<T> if (current.Data.CompareTo(current.next.Data) > 0) { Node tmp = current.next; current.next = current.next.next; tmp.next = current; if (previous == null) { head = tmp; } else { previous.next = tmp; } previous = tmp; swapped = true; } else { previous = current; current = current.next; } }// end while } while (swapped); } } // A simple class that implements IComparable<T> // using itself as the type argument. This is a // common design pattern in objects that are // stored in generic lists. public class Person : IComparable<Person> { string name; int age; public Person(string s, int i) { name = s; age = i; } // This will cause list elements // to be sorted on age values. public int CompareTo(Person p) { return age - p.age; } public override string ToString() { return name + ":" + age; } // Must implement Equals. public bool Equals(Person p) { return (this.age == p.age); } } class Program { static void Main(string[] args) { //Declare and instantiate a new generic SortedList class. //Person is the type argument. SortedList<Person> list = new SortedList<Person>(); //Create name and age values to initialize Person objects. string[] names = new string[]{"Franscoise", "Bill", "Li", "Sandra", "Gunnar", "Alok", "Hiroyuki", "Maria", "Alessandro", "Raul"}; int[] ages = new int[]{45, 19, 28, 23, 18, 9, 108, 72, 30, 35}; //Populate the list. for (int x = 0; x < 10; x++) { list.AddHead(new Person(names[x], ages[x])); } //Print out unsorted list. foreach (Person p in list) { Console.WriteLine(p.ToString()); } //Sort the list. list.BubbleSort(); //Print out sorted list. foreach (Person p in list) { Console.WriteLine(p.ToString()); } Console.WriteLine("Done"); } }
//Okay. IMyInterface : IBaseInterface<int> //Okay. IMyInterface<T> : IBaseInterface<T> //Okay. IMyInterface<T>: IBaseInterface<int> //Error. IMyInterface<T> : IBaseInterface2<T, U>
void Swap<T>( ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; }
class MyClass<T> { //… void Swap (ref T lhs, ref T rhs){…} }
class MyList<T> { // CS0693 void MyMethod<T>{...} } class MyList<T> { //This is okay, but not common. void SomeMethod<U>(){...} }
void SwapIfGreater<T>( ref T lhs, ref T rhs) where T: IComparable<T> { T temp; if(lhs.CompareTo(rhs) > 0) { temp = lhs; lhs = rhs; rhs = temp; } }
void DoSomething(){} void DoSomething<T>(){} void DoSomething<T,U>(){}
public delegate void MyDelegate<T>(T item); public void Notify(int i){} //... MyDelegate<int> m = new MyDelegate<int>(Notify);
class Stack<T> { T[] items; int index //... public delegate void StackDelegate(T[] items); }
public void StackEventHandler<T,U>(T sender, U eventArgs); class Stack<T> { //… public class StackEventArgs : EventArgs{...} public event StackEventHandler<Stack<T>, StackEventArgs> stackEvent; protected virtual void OnStackChanged(StackEventArgs a) { stackEvent(this, a); } } class MyClass { public static void HandleStackChange<T>(Stack<T> stack, StackEventArgs args){...}; } Stack<double> s = new Stack<double>(); MyClass mc = new MyClass(); s.StackEventHandler += mc.HandleStackChange;
public class MyList<T> { //... public T GetNext() { T temp = default(T); if (current != null) { temp = current.Data; current = current.Next; } return temp; } }
泛型類或接口
|
描述
|
對應的非泛型類型
|
Collection<T>
ICollection<T>
|
爲泛型容器提供基類
|
CollectionBase
ICollection
|
Comparer<T>
IComparer<T>
IComparable<T>
|
比較兩個相同泛型類型的對象是否相等、可排序。
|
Comparer
IComparer
IComparable
|
Dictionary<K, V>
IDictionary<K,V>
|
表示用鍵組織的鍵/值對集合。
|
Hashtable
IDictionary
|
Dictionary<K, V>.KeyCollection
|
表示Dictionary<K, V>中鍵的集合。
|
None.
|
Dictionary<K, V>.ValueCollection
|
表示Dictionary<K, V>中值的集合。
|
None.
|
IEnumerable<T>
IEnumerator<T>
|
表示可使用foreach 迭代的集合。
|
IEnumerable
IEnumerator
|
KeyedCollection<T, U>
|
表示有鍵值的集合。
|
KeyedCollection
|
LinkedList<T>
|
表示雙向鏈表。
|
None.
|
LinkedListNode<T>
|
表示LinkedList<T>中的節點。
|
None.
|
List<T>
IList<T>
|
使用大小可按需動態增長的數組實現 IList 接口
|
ArrayList
IList
|
Queue<T>
|
表示對象的先進先出集合。
|
Queue
|
ReadOnlyCollection<T>
|
爲泛型只讀容器提供基類。
|
ReadOnlyCollectionBase
|
SortedDictionary<K, V>
|
表示鍵/值對的集合,這些鍵和值按鍵排序並可按照鍵訪問,實現IComparer<T>接口。
|
SortedList
|
Stack<T>
|
表示對象的簡單的後進先出集合。
|
Stack
|
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=705841web