public class Int Stack int items new int100
为何使用泛型 public class Int. Stack { int[] items = new int[100]; int current = 0; public void Push(int x) { items[current++] = x; } public int Pop() { return items[current--]; } } public static void Main() { Int. Stack st = new Int. Stack(); for(int i=1; i<=10; i++) st. Push(i); int x = st. Pop(); }
为何使用泛型 public class String. Stack { string[] items = new string[100]; int current = 0; public void Push(string x) { items[current++] = x; } public string Pop() { return items[current--]; } } public static void Main() { String. Stack st = new String. Stack(); for(int i=1; i<=10; i++) st. Push(new string(‘a’, i)); string y = st. Pop(); }
为何使用泛型 public class Double. Stack { …… } public class Date. Time. Stack { …… } public class Student {. . . }; public class Student. Stack { …… } 程序缺乏可扩展性
为何使用泛型 public class Obj. Stack { object[] items = new object[100]; int current = 0; public void Push(object x) { items[current++] = x; } public object Pop() { return items[current--]; } }
为何使用泛型 public static void Main() { Obj. Stack st = new Obj. Stack(); for(int i=1; i<=10; i++) st. Push(i); int x = (int)st. Pop(); } int 装箱 Object int 拆箱 Object Obj. Stack 性能损失
为何使用泛型 public static void Main() { Obj. Stack st = new Obj. Stack(); for(int i=1; i<=10; i++) st. Push(i); int x = (int)st. Pop(); string y = (string)st. Pop(); int } int string × 拆箱 Object Obj. Stack 通过编译,但运行时出错!
为何使用泛型 public class Stack<T> { T[] items = new T[100]; int current = 0; public void Push(T x) { items[current++] = x; } public T Pop() { return items[current--]; } }
为何使用泛型 public static void Main() { Stack<int> st = new Stack<int>(); for(int i=1; i<=10; i++) st. Push(i); int x = (int)st. Pop(); string y = (string)st. Pop(); } × int string Obj. Stack 在编译时检查出错误
泛型的定义 � 泛型类(Generic � class) 声明:modifier class Class. Name <T 1, T 2, T 3 …> 类型 参数 public class Stack<T> {}
泛型的定义 � 泛型类 声明:modifier class Class. Name <T 1, T 2, T 3 …> � 创建:abstract type concrete type � public class Stack<T> {} Stack<int> st = new Stack<int>(); 替换为 实际类型
泛型的定义 � 泛型结构 声明:modifier struct Struct. Name <T 1, T 2, T 3 …> � 创建:abstract type concrete type �
泛型的定义 � 成员与类型参数 字段类型 � 方法参数类型 � 方法返回类型 � public class Stack<T> { T[] items = new T[100]; int current = 0; public void Push(T x) { items[current++] = x; } public T Pop() { return items[current--]; } }
泛型的定义 � 成员与类型参数 方法中局部变量类型 � 构造函数定义中不出现类型参数! � public class Stack<T> { public T Peek() { T t = items[current]; return t; } public Stack() {} public Stack(int size) { items = new T[size]; } }
类型限制 � 主要限制 � 值类型限制 public class Stack<T> where T: struct
类型限制 � 主要限制 值类型限制 � 引用类型限制 � public class Stack<T> where T: struct public class Queue<T> where T: class public class Dictionary<K, D> where K: struct where D: class
类型限制 � 主要限制 � 次要限制 � 接口限制 public class Pri. Queue<T> where T: IComparable { public void Push(T x) { for(int i=0; i<items. length; i++) if(x. Compare. To(items[i]) >= 0) //. . . } }
类型限制 � 主要限制 � 次要限制 接口限制 � 基类限制 � public class Student {} public class Undergraduate: Student {} public class Graduate: Student {} public class Pri. Queue<T> where T: Student Pri. Queue<Student> q 1 = new Pri. Queue<Student>(); Pri. Queue<Graduate> q 2 = new Pri. Queue<Graduate>(); Pri. Queue<string> q 3 = Pri. Queue<string>(); ×
类型限制 � 主要限制 � 次要限制 接口限制 � 基类限制 � 构造函数限制 � public class Student { public Student() {} } public class Queue<T> where T: Student { public Queue(int size) { items = new T[size]; for(int i=0; i<size; i++) items[i] = new T(); } }
泛型与继承 � 开放类型:含有类型参数 T t 1; � T[] array 1; � Stack<T> st 1; � Dictionary<int, T> dict 1; � � 封闭类型:不含类型参数 object t 2; � Stack<int> st 2 � Dictionary<int, Student> dict 2 � Queue<Stack<int>> queue 1; �
泛型与继承 � 泛型类(及其构造类型) class A<T> � class B<S, T> : A<T> � class C<S> : A<int> � class D<R, S, T> : B<string, T> � class E<S> : A<T> × � class F<S> : B<S, T> × � class G<S> : B<S, S> � class H<S> : D<S, int, double> �
元组 � Tuple<T 1, T 2>:二元组 Tuple<int, int> t 1 = new Tuple<int, int>(4, 5); int x 1 = t 1. Item 1; int x 2 = t 1. Item 2;
元组 � Tuple<T 1, T 2>:二元组 Tuple<int, int> t 1 = new Tuple<int, int>(4, 5); int x 1 = t 1. Item 1; int x 2 = t 1. Item 2; t 1. Item 1 = 10; × 分量不允许修改!
元组 � Tuple<T 1, T 2>:二元组 � Tuple<T 1, T 2, T 3>:三元组 Tuple<string, char, int> t 1 = new Tuple<string, char, int>("", 'a', 5); string s 1 = new string(t 1. Item 2, t 1. Item 3);
元组 � 长元组:使用别名 Tuple<string, char, int> t 1 = Tuple<string, char, int> t 2 = Tuple<char, int, char, int> t 3 Tuple<char, int, char, int> t 4 new Tuple<string, char, int>("", 'a', 5); new Tuple<string, char, int>("", 'x', 7); = new Tuple<char, int, char, int>('I', 1, 'E', 3); = new Tuple<char, int, char, int>('W', 3, 'C', 2); using STrp = Tuple<string, char, int>; using CTrp = Tuple<char, int, char, int>; STrp t 1 = new STrp("", 'a', 5); STrp t 2 = new STrp("", 'x', 7); CTrp t 3 = new CTrp('I', 1, 'E', 3); CTrp t 4 = new CTrp('W', 3, 'C', 2);
元组 � 更多分量:元组的元组 using ITrp = Tuple<int, int>; ITrp t 1 = new ITrp(-1, -2, -3); Tuple<char, char> t 2 = new Tuple<char, char>('P', 'Q', 'R'); ITrp t 3 = new ITrp(10, 20, 30); using NTrp = Tuple<ITrp, Tuple<char, char>, ITrp>; NTrp t 4 = new NTrp(t 1, t 2, t 3);
可空类型 � 对每个可为空的值类型增加一个新定义? � 泛型解决方案:T+null int? = Nullable<int> Nullable<T> float? = Nullable<float> Size? = Nullable<Size> ……
可空类型 � Nullable<T> where T: struct bool Has. Value T Value operator == !=
可空类型 � 类型转换 T Nullable<T> T object Nullable<T> (null? )
泛型方法 public class My. Math { public static void Swap(ref int x, ref int y) {int t=x; x=y; y=t; } } public static void Main() { int a = 4, b = 5; My. Math. Swap(a, b); }
泛型方法 public class My. Math { public static void Swap(ref int x, ref int y) {int t=x; x=y; y=t; } } public static void Main() { int a = 4, b = 5; My. Math. Swap(a, b); double x = 1. 2, y = 3. 4; } ?
泛型方法 public class My. Math<T> { public static void Swap(ref T x, ref T y) { T t=x; x=y; y=t; } public static void Sqrt(double x) {. . . } public static void Solve. Equation(int[] x) {. . . } } public static void Main() { int a = 4, b = 5; My. Math<int>. Swap(a, b); double x = 1. 2, y = 3. 4; My. Math<double>. Swap(ref x, ref y); }
泛型方法 public class My. Math<T> { public static void Swap(ref T x, ref T y) { T t=x; x=y; y=t; } public static void Sqrt(double x) {. . . } public static void Solve. Equation(int[] x) {. . . } } public static void Main() { int a = 4, b = 5; My. Math<int>. Swap(a, b); double x = 1. 2, y = 3. 4; My. Math<double>. Swap(ref x, ref y); My. Math<double>. Sqrt(x); My. Math<int[]>. Solve. Equation(3, -1, 5); } ?
泛型方法 public class My. Math { public static void Swap<T>(ref T x, ref T y) { T t=x; x=y; y=t; } public static void Sqrt(double x) {. . . } public static void Solve. Equation(int[] x) {. . . } } public static void Main() { int a = 4, b = 5; My. Math<int>. Swap(a, b); double x = 1. 2, y = 3. 4; My. Math<double>. Swap(ref x, ref y); My. Math. Sqrt(x); My. Math. Solve. Equation(3, -1, 5); }
泛型方法 � 同样可以进行类型限制 public T Max<T> (T x, T y) where T: IComparable { if(x. Compare. To(y) >= 0) return x; else return y; }
泛型方法 � 同样可以进行重载 public abstract class GA { public abstract void F 1<T>(T t 1, T t 2); } public class GB<T> : GA { public override void F 1<R>(R r 1, R r 2) { } public virtual void F 2<S>(S s, T t) { } } public class GC<T> : GB<int> { public override void F 1<R>(R r 1, R r 2) { } public override void F 2<S>(S s, int i) { } }
泛型方法 � 同样可以作为扩展方法 public class My. Math { public static void Sqrt(double x) {. . . } public static void Solve. Equation(int[] x) {. . . } } public static class My. Extension { public static void Swap<T>(this My. Math m, ref T x, ref T y) { T t=x; x=y; y=t; } }
泛型接口 � 定义 � 类型参数 public interface IComparable<T> { int Compare. To(T other); }
泛型接口 � 定义 � 类型参数 � 类型限制 public interface IOutput<T> where T : struct { } public interface IPay<T> where T : Icurrency, new() { }
泛型接口 � 常用泛型接口 IEnumerator<T> � IEnumerable<T> � ICollection<T> � Ilist<T> � IComparable<T> � IComparer<T> � IEquality. Comparer � IDictionary<K, V> �
泛型集合与循环遍历 int[] i. Array = new int[]{1, 3, 5, 7, 9}; foreach(int i in i. Array) Console. Write. Line(2*i+1); List<Student> students = new List<Student>(); Students. Add(new Student()); . . . foreach(Student s in students) Console. Write. Line(s. Name); foreach(T t in t. Collection); Console. Write. Line(t); t. Collection: 类型实现IEnumerable/ IEnumerable<T>
泛型集合与循环遍历 public interface IEnumerable { IEnumerator Get. Enumerator(); } public interface IEnumerable<T> : IEnumerable { IEnumerator<T> Get. Enumerator(); }
泛型集合与循环遍历 � 可遍历类型 � 支持IEnumerable<T>或IEnumerable<T> public class Priority. Queue<T> : IEnumerable<T> where T : IComparable<T> { List<T> list; public Priority. Queue(IEnumerable<T> ts) { list = new List<T>(ts); } }
泛型集合与循环遍历 � 可遍历类型 � 支持IEnumerable<T>或IEnumerable<T> public class Priority. Queue<T> : IEnumerable<T> where T : IComparable<T> { List<T> list; public Priority. Queue(IEnumerable<T> ts) { list = new List<T>(ts); } public IEnumerator<T> Get. Enumerator() { return list. Get. Enumerator(); } IEnumerator IEnumerable. Get. Enumerator() { return list. Get. Enumerator(); } }
泛型集合与循环遍历 � 遍历器 IEnumerable<Student> foreach(Student s in students) Console. Write. Line(s. Name); Get. Enumerator() Move. Next(): true Before Move. Next(): true Running yield return Yield break After IEnumerator<Student> Suspending Move. Next(): false
泛型集合与循环遍历 � 遍历器 � 实现Get. Enumerator方法 public class Num : IEnumerable<int> { public IEnumerator Get. Enumerator() { for (int i = 1; i < 10; i++) yield return i; } }
泛型集合与循环遍历 � 遍历器 IEnumerable<int> foreach(int i in Num) Console. Write. Line(i); Get. Enumerator() Move. Next(): true Before Move. Next(): true Running yield return Yield break After IEnumerator<int> Suspending Move. Next(): false
泛型委托 � 委托(Delegate)回顾 � 类似于C/C++中的函数指针 � 采用面向对象的方法来封装方法(子程序) delegate double Func(double x); Func f 1 = new Func(Math. Log); double y = f 1(0. 5); //double y = Math. Log(0. 5); f 1 = new Func(Math. Sqrt); y = f 1(10); //y = Math. Sqrt(10); Func[] fs = new Func[]{Math. Log, Math. Sin, Math. Cos, Math. Tan); foreach(Func f in fs) Console. Write. Line(f(0. 5));
泛型委托 � 定义 delegate T Func(T x, T y) where T: Icomparable;
泛型委托 � 定义 � 使用 delegate T Func(T x, T y) where T: IComparable; Func<int> f 1 = new Func(Math. Max<int>); int x = f 1(5, 7); Func<double> f 2 = new Func(Math. Max<double>); double y = f 2(0. 5, 0. 7); f 2 = new Func(Math. Power); double z = f 1(x, y);
泛型委托 � 高级用法 � 封装匿名方法 delegate T Func(T x); Func f 1 = delegate(int x) {return x*x; }; int x = f 1(5); Func f 1 = delegate {return 10; }; x = f 1(7); f 1 = delegate(int x) {int y=x; while(x>1) y*=(--x); return y; }; x = f 1(7);
泛型委托 � 高级用法 � 封装匿名方法 � 封装Lambda表达式 � LINQ查询 public this static IEnumerable<T> Where<T>( IEnumerable<T> source, Func<T, bool> predicate); static IEnumerable<S> Select<T, S>( IEnumerable<T> source, Func<T, S> selector); var expr = customers. Where(c => c. Country == Countries. Italy). Select(c => c. Name);
- Slides: 77