说明:第2部分:第12章:泛型P(185)
12.1 本章内容:
- · FCL中的泛型
- · 泛型基础接口
- · 泛型接口
- · 泛型委托
- · 委托和接口的逆变和协变泛型类型实参
- · 泛型方法
- · 泛型和其它成员
- · 可验证性和约束
/* ================================================= */ #if !DEBUG #pragma warning disable 660, 661, 219 #endif using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; public static class Generics { public static void Main() { Performance.ValueTypePerfTest(); Performance.ReferenceTypePerfTest(); GenericArray(); OpenTypes.Go(); GenericInheritance.Go(); Constraints.Go(); } ////// / 演示泛型方法的简单使用// /// private static void GenericArray() //P238 { //创建并初始化字节数组 Byte[] byteArray = new Byte[] { 5, 1, 4, 2, 3 }; // 调用Byte[]排序算法 Array.Sort (byteArray); // 调用Byte[]二分搜索算法 Int32 i = Array.BinarySearch (byteArray, 1); Console.WriteLine(i); // 显示 "0" } } /// /// 性能比较 List 与 ArrayList /// internal static class Performance //P235 { public static void ValueTypePerfTest() { const Int32 count = 10000000; using (new OperationTimer("List ")) { List l = new List (); for (Int32 n = 0; n < count; n++) { l.Add(n); // 不发生装箱 Int32 x = l[n]; // 不发生装箱 } l = null; // 确保进行垃圾回收 } using (new OperationTimer("ArrayList of Int32")) { ArrayList a = new ArrayList(); for (Int32 n = 0; n < count; n++) { a.Add(n); // 装箱 Int32 x = (Int32)a[n]; // 拆箱 } a = null; // 确保进行垃圾回收 } } public static void ReferenceTypePerfTest() { const Int32 count = 10000000; using (new OperationTimer("List ")) { List l = new List (); for (Int32 n = 0; n < count; n++) { l.Add("X"); // 复制引用 String x = l[n]; // 复制引用 } l = null; // 确保进行垃圾回收 } using (new OperationTimer("ArrayList of String")) { ArrayList a = new ArrayList(); for (Int32 n = 0; n < count; n++) { a.Add("X"); // 复制引用 String x = (String)a[n]; // 检查强制类型&复制引用 } a = null; // 确保进行垃圾回收 } } // 这个类用于进行运算性能计时 private sealed class OperationTimer : IDisposable { private Stopwatch m_stopwatch; private String m_text; private Int32 m_collectionCount; public OperationTimer(String text) { PrepareForOperation(); m_text = text; m_collectionCount = GC.CollectionCount(0); // 这个应该是方法的最后一句,从而最大程序保证计时的准确性 m_stopwatch = Stopwatch.StartNew(); } public void Dispose() { Console.WriteLine("{0} (GCs={1,3}) {2}", (m_stopwatch.Elapsed), GC.CollectionCount(0) - m_collectionCount, m_text); } private static void PrepareForOperation() { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } } } // /// /// 开放类型,开放类型:具有泛型类型参数的类型称为开放类型 /// internal static class OpenTypes//P239 { public static void Go() { Object o = null; // Dictionary<,> 是开放类型,有2个类型的参数 Type t = typeof(Dictionary<,>); // 尝试创建改类型的实例(失败) o = CreateInstance(t); Console.WriteLine(); // DictionaryStringKey<> 是开类型 t = typeof(DictionaryStringKey<>); // 尝试创建该类型的实例(失败) o = CreateInstance(t); Console.WriteLine(); // DictionaryStringKey 是封闭类型 t = typeof(DictionaryStringKey); // 尝试创建该类的一个实例(成功) o = CreateInstance(t); // 证明它确实能够工作 Console.WriteLine("Object type=" + o.GetType()); } private static Object CreateInstance(Type t) { Object o = null; try { o = Activator.CreateInstance(t); Console.Write("Created instance of {0}", t.ToString()); } catch (ArgumentException e) { Console.WriteLine(e.Message); } return o; } // 一个部分指定的开放类型 internal sealed class DictionaryStringKey : Dictionary { } } /// /// 泛型类型和继承 P(240) /// internal static class GenericInheritance { public static void Go() { /看看下面2个方法/ SameDataLinkedList(); DifferentDataLinkedList(); } private static void SameDataLinkedList() { //相同数据类型的链表 Node head = new Node ('C'); head = new Node ('B', head); head = new Node ('A', head); Console.WriteLine(head.ToString()); //这里显示“ABC” } private static void DifferentDataLinkedList() { //不能数据类型的链表 Node head = new TypedNode ('.'); head = new TypedNode (DateTime.Now, head); head = new TypedNode ("Today is ", head); Console.WriteLine(head.ToString()); } private sealed class Node { public T m_data; public Node m_next; public Node(T data) : this(data, null) { } public Node(T data, Node next) { m_data = data; m_next = next; } public override String ToString() { return m_data.ToString() + ((m_next != null) ? m_next.ToString() : null); } } private class Node { protected Node m_next; public Node(Node next) { m_next = next; } } /// /// 定义一个链表节点类 /// /// private sealed class TypedNode : Node { public T m_data; public TypedNode(T data) : this(data, null) { } public TypedNode(T data, Node next) : base(next) { m_data = data; } public override String ToString() { return m_data.ToString() + ((m_next != null) ? m_next.ToString() : null); } } private sealed class GenericTypeThatRequiresAnEnum { static GenericTypeThatRequiresAnEnum() { if (!typeof(T).IsEnum) { throw new ArgumentException("T must be an enumerated type"); } } } } /// /// 泛型方法演示 P247 /// internal static class GenericMethods { public static void Go() { GenericType gts = new GenericType ("123"); Int32 n = gts.Converter (); CallingSwap(); CallingSwapUsingInference(); Display("Jeff"); // 调用 Display(String) Display(123); // 调用 Display (T) Display("Aidan"); // 调用 Display (T) } private static void Swap(ref T o1, ref T o2) { T temp = o1; o1 = o2; o2 = temp; } private static void CallingSwap() { Int32 n1 = 1, n2 = 2; Console.WriteLine("n1={0}, n2={1}", n1, n2); Swap (ref n1, ref n2); Console.WriteLine("n1={0}, n2={1}", n1, n2); String s1 = "Aidan", s2 = "Kristin"; Console.WriteLine("s1={0}, s2={1}", s1, s2); Swap (ref s1, ref s2); Console.WriteLine("s1={0}, s2={1}", s1, s2); } static void CallingSwapUsingInference() { Int32 n1 = 1, n2 = 2; Swap(ref n1, ref n2); // 调用 Swap // String s1 = "Aidan"; // Object s2 = "Kristin"; // Swap(ref s1, ref s2); // 错误, 不能推断类型 } private static void Display(String s) { Console.WriteLine(s); } private static void Display (T o) { Display(o.ToString()); // 调用 Display(String) } internal sealed class GenericType { private T m_value; public GenericType(T value) { m_value = value; } public TOutput Converter () { TOutput result = (TOutput)Convert.ChangeType(m_value, typeof(TOutput)); return result; } } } internal static class Constraints { public static void Go() { Boolean b = ComparingGenericVariables.Op.M (null, null); } private static Boolean MethodTakingAnyType (T o) { T temp = o; Console.WriteLine(o.ToString()); Boolean b = temp.Equals(o); return b; } private static T Min (T o1, T o2) where T : IComparable { if (o1.CompareTo(o2) < 0) return o1; return o2; } private static void CallMin() { Object o1 = "Jeff", o2 = "Richter"; //Object oMin = Min// Error CS0309 } internal sealed class OverloadingByArity { // 可以定义以下类型 internal sealed class AType { } internal sealed class AType { } internal sealed class AType { } // 错误:与没有约束的AType 冲突 //internal sealed class ATypewhere T : IComparable // 错误: 与AType{ } 冲突 //internal sealed class AType{ } internal sealed class AnotherType { //可以定义以下方法,参数个数不同 private static void M() { } private static void M() { } private static void M () { } // 错误: 与没有约束 M 冲突 //private static void M() where T : IComparable // 错误: 月 M{ } 冲突 //private static void M() { } } } internal static class OverridingVirtualGenericMethod { internal class Base { public virtual void M() where T1 : struct where T2 : class { } } internal sealed class Derived : Base { public override void M () /*where T3 : struct //错误 where T4 : class */ //错误 { } } } /// /// 主要约束演示 P252 /// internal static class PrimaryConstraints { internal static class PrimaryConstraintOfStream where T : Stream { public static void M(T stream) { stream.Close(); // 正确 } } internal static class PrimaryConstraintOfClass where T : class // P252 { public static void M() { #pragma warning disable 219 T temp = null; // 允许,因为T肯定是引用类型 #pragma warning restore 219 } } internal static class PrimaryConstraintOfStruct where T : struct//P253 { public static T Factory() { // 允许,因为所有的值类型都隐式有一个公共无参构造器 return new T(); } } } /// /// 次要约束 P253 /// internal static class SecondaryConstraints { private static List ConvertIList (IList list) where T : TBase { List baseList = new List (list.Count); for (Int32 index = 0; index < list.Count; index++) { baseList.Add(list[index]); } return baseList; } private static void CallingConvertIList() { // 构造并初始化一个List (它实现了IList IList) ls = new List (); ls.Add("A String"); // 1.将 IList 转化成 IList IList