之前我們學習過對象初始化語法,現在我們看一下集合初始化語法:這種語法特性,讓你可以用與填充基礎數組類似的語法,來填充ArrayList或List<Y>等容器。說明,只能支持Add()方法的類使用集合初始化語法,這是ICollection<T>或ICollection接口決定的。如建立一個point集合類,可以如下表示:List<Point> mylit = new List<Point>{ new point{x=1,y=1}, new point{x=2,y=2}, ...};這種語法的好處是減少鍵盤輸入,但是壞處則是影響可讀性。此命名空間下,包括幾種泛型類。List<T>,使用最廣,用以動態調整的類型。Stack<T>,棧,后進先出的數據集合,包含push和pop方法,分別比歐式進棧和出棧。Queue<T>,隊列,先進先出的數據集合,包括Dequeue和Enqueue方法,分別表示在移除開始處對象(并返回)和在隊列末尾添加一個對象,除此之外,還有Peek方法,返回隊列開始處對象,但并不移除。SortedSet<T>,這個類中的項是自動排序的,在插入和移除之后,也能自動排序,因此該類十分有用。
四、創建自定義的泛型方法/泛型結構和類。
傳統方法,交換兩個整數:Swap(ref int a, ref int b){ int temp; temp = a; a = b; b = temp;}如果我們繼續要交換兩個Person對象,則我們必須編寫一個swap的新版本:Swap(refPersona, refPersonb){Persontemp; temp = a; a = b; b = temp;}如果需要交換其他的數據,則需要定義更多的方法,這就會給維護帶來麻煩,如果想要有單一的方法,我們需要創建操作Object類型的方法,但這樣會導致裝箱、拆箱,類型安全,顯示轉換等問題。如果你要創建的方法重載只是輸入參數不同,可以使用泛型。方法如下:Swap<T>(ref T a, ref T b){T temp; temp = a; a = b; b = temp;}我們還可以創建泛型類或結構:public class Point<T>{}其中,我們可以是一個雙精度的point也可以是一個int的point。1、default(T),和泛型一塊兒使用的時候,它表示一個類型參數的默認值。這非常有用,因為一個泛型類型預先并不知道實際的真為輔,因此無法安全的假設默認值是什么。默認值如下:數值的默認值為0;引用類型的默認值是null;一個結構的字段被設為0(值類型)或null(引用類型)。2、泛型基類,泛型類可以作為其他類的基類,它可以定義許多虛方法和抽象方法。但是要做到這些,泛型類需要遵循一些守則:首先,如果一個非泛型類型擴展了一個泛型類,派生類必須指定一個類型參數。public class B:A<string>{}.其中A類為我們自定義的泛型類。其次,如果泛型基類定義了泛型虛方法或抽象方法,派生類型必須使用指定類型參數重寫泛型方法。最后,如果派生類型也是泛型,則它能夠(可選的)重用類型占位符。不過要注意派生類必須遵照基類中的任何約束。
五,類型參數的約束
如本節描述,任何泛型都必須至少有一個類型參數,并在與泛型類型或參數交互時指定該類型參數,這可以使我們構建類型安全的代碼。.net平臺使用where關鍵字可以得到更加具體的類型參數信息。下面幾種約束表示如下:where T:struct,該類型參數<T>必須在其繼承鏈中包含System.ValueType值類型,即必須為結構。where T : class,和上面相反,不能包含值類型,必須為引用類型。where T : new(),該類型參數<T>必須包含一個默認的構造函數,因為無法預知子定義構造函數格式,所以如果泛型類型必須創建一個類型參數的實例,這將是非常有用的。注意,在有多個約束的時候,此約束必須列在末尾。where T : NameOfBaseClass,該類型參數<T>必須派生于NameOfBaseClass指定的類。where T : NameOfInterface,同上,必須派生于指定接口,多個接口必須用逗號隔開。例如,如果要指定泛型智能操作結構,可以這樣:Swap<T>(ref T a, ref T b) where T : struct {....}。以這種方式約束了Swap方法就不能再對其他如string對象進行交換了,因為string是引用類型。