---------- 陣列, 泛型List, ArrayList 陣列 string[] weekDays = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; int[] myIntArray = new int[5] { 1, 2, 3, 4, 5 }; string[] saColumns = "column1,column2,column3".Split(','); 建議改以泛型List替代如下 List dinosaurs = new List(); dinosaurs.Add("Tyrannosaurus"); dinosaurs.Add("Amargasaurus"); dinosaurs.Add("Mamenchisaurus"); ArrayList則是適用於非明確型別, 因為存取值時須多進行型別轉換處理(boxing/unboxing) ---------- 泛型記住一個重點就可以了: 表示碰到T就會以指定的取代! 優點是在編譯階段為強制型別, 可預先檢查出錯誤的型別呼叫, 減少boxing/unboxing的型別轉換. 詳細請參考(C#泛型語法測試)段落. public class Generic { public T Field; } public static void Main() { Generic g = new Generic(); g.Field = "A string"; //... Console.WriteLine("Generic.Field = \"{0}\"", g.Field); Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName); } ---------- 優點範例: 使用泛型 GenericList 類別建立整數清單。 您只要變更型別引數,就能輕鬆修改下列的程式碼來建立字串清單或其他任何自訂型別的清單: class TestGenericList { static void Main() { // int is the type argument List list = new List(); for (int x = 0; x < 10; x++) { list.AddHead(x); } foreach (int i in list) { System.Console.Write(i + " "); } System.Console.WriteLine("\nDone"); } } ---------- Sample: 重點: 1 第1個函數就可以取代後面3個函數. 2 雖然好用. 但若泛型語法不像此例單純時, 呼叫者需知道如何呼叫的方式. 搭配IDE整合環境就可以忽略此問題. public static void SetItem(string sKey, T vInput) { HttpContext.Current.Session[sKey] = vInput; } public static void SetItem(string sKey, DateTime dValue) { SetItem(sKey, dValue); } public static void SetItem(string sKey, string sValue) { SetItem(sKey, sValue); } public static void SetItem(string sKey, int iValue) { SetItem(sKey, iValue); } ---------- List List listClass = new List(); using System; using System.Collections.Generic; public class Example { public static void Main() { List dinosaurs = new List(); Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity); dinosaurs.Add("Tyrannosaurus"); dinosaurs.Add("Amargasaurus"); dinosaurs.Add("Mamenchisaurus"); dinosaurs.Add("Deinonychus"); dinosaurs.Add("Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) { Console.WriteLine(dinosaur); } Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity); Console.WriteLine("Count: {0}", dinosaurs.Count); Console.WriteLine("\nContains(\"Deinonychus\"): {0}", dinosaurs.Contains("Deinonychus")); Console.WriteLine("\nInsert(2, \"Compsognathus\")"); dinosaurs.Insert(2, "Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) { Console.WriteLine(dinosaur); } Console.WriteLine("\ndinosaurs[3]: {0}", dinosaurs[3]); Console.WriteLine("\nRemove(\"Compsognathus\")"); dinosaurs.Remove("Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) { Console.WriteLine(dinosaur); } dinosaurs.TrimExcess(); Console.WriteLine("\nTrimExcess()"); Console.WriteLine("Capacity: {0}", dinosaurs.Capacity); Console.WriteLine("Count: {0}", dinosaurs.Count); dinosaurs.Clear(); Console.WriteLine("\nClear()"); Console.WriteLine("Capacity: {0}", dinosaurs.Capacity); Console.WriteLine("Count: {0}", dinosaurs.Count); } } /* This code example produces the following output: Capacity: 0 Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus Capacity: 8 Count: 5 Contains("Deinonychus"): True Insert(2, "Compsognathus") Tyrannosaurus Amargasaurus Compsognathus Mamenchisaurus Deinonychus Compsognathus dinosaurs[3]: Mamenchisaurus Remove("Compsognathus") Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus TrimExcess() Capacity: 5 Count: 5 Clear() Capacity: 5 Count: 0 */ ---------- C#泛型語法測試: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2_Template { class Program { static void Show(T t) { Console.Write("Show -> "); Type tp = t.GetType(); string info = string.Format("{0}, {1}", tp.Name, t.ToString()); Console.WriteLine(info); } static void Main(string[] args) { //## C#泛型函式測試 Console.WriteLine("## C#泛型函式測試"); Show(5); Show("string1"); //## 泛型類別傳遞參數測試 Console.WriteLine("\r\n## 泛型類別傳遞參數測試"); MyTClass tc = new MyTClass(); tc.SetInstance(3); // 以泛型傳入INT32 tc.Dump(); int ii = tc.GetInstance(); // 以泛型取回INT32 Console.WriteLine(ii); tc.SetInstance("str3."); // 以泛型傳入String tc.Dump(); string ss = tc.GetInstance(); // 以泛型取回String Console.WriteLine(ss); } } class MyTClass { private object aInstance; // 以實體物件儲放樣版物件,測試樣版物件與實體物件的互通性。 public void SetInstance(T t) { aInstance = t; // 以實體儲放樣版。 } public T GetInstance() { return (T)aInstance; // 自實體物件取回樣版物件。 } public void Dump() { if (aInstance == null) { Console.WriteLine("aInstance is null."); return; } Type tp = aInstance.GetType(); string dumpInfo = string.Format("MyTClass.Dump -> Type: {0}, ToString: {1}", tp.Name, aInstance.ToString()); Console.WriteLine(dumpInfo); } } } 下面是執行結果: ## C#泛型函式測試 Show -> Int32, 5 Show -> String, string1 ## 泛型類別傳遞參數測試 MyTClass.Dump -> Type: Int32, ToString: 3 3 MyTClass.Dump -> Type: String, ToString: str3. str3. 請按任意鍵繼續 . . . ---------- 這個範例在幾個地方使用了型別參數 T,這些地方通常需要使用具象型別來表示清單中儲存的項目型別。 這個參數可以用於: 做為 AddHead 方法中的方法參數型別。 做為公用方法 GetNext 的傳回型別,以及巢狀 Node 類別中的 Data 屬性。 做為巢狀類別中私用成員資料的型別。 請注意,T 可用於巢狀 Node 類別。當 GenericList 以具象型別執行個體化時 (例如執行個體化為 GenericList),則每次出現的 T 項目都會以 int 取代。 // type parameter T in angle brackets public class GenericList { // The nested class is also generic on T. private class Node { // T used in non-generic constructor. public Node(T t) { next = null; data = t; } private Node next; public Node Next { get { return next; } set { next = value; } } // T as private member data type. private T data; // T as return type of property. public T Data { get { return data; } set { data = value; } } } private Node head; // constructor public GenericList() { head = null; } // T as method parameter type: public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } } ---------- private T CreateNewInstanceOfGenericType(T tGeneric) { //return (T)Activator.CreateInstance(typeof(T), new object[] { param }); return (T)Activator.CreateInstance(typeof(T)); } ---------- Two options to return NULL from a generic method: Return default(T) which means you'll return null if T is a reference type (or a nullable value type), 0 for int, '\0' for char etc T tForm2 = default(T); Restrict T to be a reference type with the where T : class constraint and then return null as normal ---------- C#泛型(Generic Class)。 C++ 為Template Class, 樣版類別 public static bool ZFind(string[] ar, string sToFind) { // CodeHelper for Generic Type sample string s1 = Array.Find(ar, (p => p == sToFind)); return s1 != null; }