標籤:style blog http color 使用 os io 2014
用泛型實現參數化型別
1. 泛型更好滴編譯時間檢查,能消除很多裝箱和拆箱
2. 泛型字典 Dictionary<TKey, TValue>
1 static Dictionary<string,int> CountWords(string text) 2 { 3 Dictionary<string,int> frequencies; 4 frequencies = new Dictionary<string,int>(); 5 6 string[] words = Regex.Split(text, @"\W+"); 7 8 foreach (string word in words) 9 {10 if (frequencies.ContainsKey(word))11 {12 frequencies[word]++;13 }14 else15 {16 frequencies[word] = 1;17 }18 }19 return frequencies;20 }21 22 ...23 string text = @"Do you like green eggs and ham?24 I do not like them, Sam-I-am.25 I do not like green eggs and ham.";26 27 Dictionary<string, int> frequencies = CountWords(text);28 foreach (KeyValuePair<string, int> entry in frequencies)29 {30 string word = entry.Key;31 int frequency = entry.Value;32 Console.WriteLine("{0}: {1}", word, frequency);33 }
3. 泛型有兩種:泛型型別(類、介面、委託和結構,但沒有泛型枚舉)和泛型方法。
型別參數是真實類型的預留位置,這些真實的類型稱為類型實參(type argument)。使用泛型型別或方法時,要是有真實的類型代替。上面的泛型字典在使用時,類型實參string代替TKey,int代替TValue。
4. 類型約束
參考型別約束:struct RefSample<T> where T : Class 約束T的類型為參考型別,當然T 也可以約束為介面,數組,委託或者其他的已知的參考型別
有效約束:RefSample<IDisposable> RefSample<string> RefSample<int[]>
無效的約束:RefSample<Guid> RefSample<int>
被約束的類型與類型本身有差別的,這裡的類型本身是個實值型別。
實值型別約束:class ValSample<T> where T :struct 約束T為實值型別,包括枚舉,但排除可空類型。
有效約束:ValSample<int> ValSample<FileMode>
無效的約束:ValSample<object> ValSample<StringBuilder>
建構函式約束:T : new(), 必須是所有參數約束的最後一個約束。它將檢查類型的實參是否有用於建立類型執行個體的無參建構函式。
適用於:所有實值型別;所有沒有顯式聲明建構函式的非靜態、非抽象類別;所有顯式聲明了一個公用無參建構函式的非抽象類別。
轉換類型約束:
組合約束案例:
5. 進階泛型
靜態欄位:若在SomeClass中聲明了靜態欄位X,不管SomeClass建立多少個執行個體, 也不管從SomeClass派生多少個類型,都只有一個SomeClass.X欄位。
JIT如何處理泛型?
泛型迭代:在C#2 中遍曆由實值型別元素構成的泛型集合(List<int>)根本就不會裝箱。
反射和泛型:typeof、System.Type