用泛型实现参数化类型
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 else 15 { 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
C# in Depth Third Edition 学习笔记-- C#2.0: 解决C#1.0的问题 1 泛型