这本书讲解 C# 语言十分详细,我将其中的重要内容整理成条款,以备忘。
1. 泛型是为在不同的数据类型上执行相同指令的情况专门设计的一种语言特性,它允许我们声明类型参数化的代码,即用不同的类型进行实例化。泛型类型是类型的模板,类型是实例的模板。 C# 包含 5 种泛型:类、结构、接口、委托和方法。
2. 泛型类不是实际的类,而是类的模板 ,必须先从它们创建实际的类 类型,然后才能创建这个类类型的实例。
3. 声明泛型类与声明普通类的区别: 1. 在类名之后放置一组尖括号 <> 。 2. 在尖括号中用通过逗号分割的类型占位符来表示要提供的类型 ( 类型参数 ) 。 3. 在泛型类声明的主体中使用类型参数来表示应被替代的类型。如:
Class SomeClass <T1, T2>
{
public T1 var1 = new T1();
public T2 var2 = new T2();
}
4. 使用泛型类时要使用类型实参来替换掉类型占位符 ( 类型形参 ) ,从而构建实际的类类型,如: SomeClass <short, int> 。通过同一个泛型类可以构建出很多不同的类 类型,他们都是彼此独立的 ,就如普通的非泛型类一样。
5. 让编译器知道哪些类型可以作为类型实参的额外信息 叫做约束 (constraints) 。只有符合约束的类型才能作为类型实参。每一个有约束的类型参数都有自己的 where 子句。如果一个类型参数有多个约束,则在 where 子句中用逗号隔开,但多个参数的约束间不能有任何分隔符 。
6. where 子句在类型参数的右尖括号之后 列出, where 子句之间不能有分隔符,但次序不限。 where 是上下文关键字,所以在其他上下文中可以使用 ( 但不推荐 ) 。
7. 约束共有五类: 1 . 类名:只有这个类型或者它的子类 才能用作类型实参。 2 .class :任何引用类型 ,包括类、数组、委托和接口都可用作类型实参。 3 .struct :类型实参必须为值类型 。 4 . 接口:类型实参只能是此接口或实现了此接口的类型 。 5 .new() :任何带有无参公共构造函数的类型 都可作为实参。 ( 构造函数约束 )
8. where 子句的次序虽然不限,但同一个类型参数的约束 ( 即 where 子句的约束 ) 必须有特定顺序。类名、 class 、 struct 最多只能有一个 ,且必须放在第一位 ;其后可以有 0 至任意多个 接口约束 ;如果有构造函数约束则必须放在最后 。
9. 泛型结构的规则和约束条件和泛型类是一样的。
10. 泛型接口允许我们编写成员参数和返回类型是类型参数的接口。在接口名后的尖括号中加入类型参数。实现了不同类型参数的接口是不同的接口 。可以在非泛型类型 中实现泛型 接口 。如: class Simple : IDo<int>, IDo<string> {} 。
11. 泛型接口的实现必须唯一 。在类型实现泛型接口时不能因为类型实参而导致出现一个类型实现了多个相同的接口。如: class Simple : IDo<int>, IDo<T> {} ,当 T 为 int 时,两个接口一样,这是不允许的。但泛型接口的名字不会和非 泛型接口冲突 。如: interface IDo<T> 和 interface IDo 的声明可同时存在。
12. 声明泛型委托时要在委托名和参数列表之间的尖括号中放置类型参数列表。如下: delegate void MyDelegate<T>(T value); 。
13. Func 委托有 5 种形式:最简单的是 public delegate TResult Func <TResult>(); 不接受参数但返回值类型为 TResult ,然后分别是 public delegate TResult Func <T, TResult>(T arg) ; public delegate TResult Func <T1, T2, TResult>(T1 arg1, T2 arg2) ; public delegate TResult Func <T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3) ; public delegate TResult Func <T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4) 。 注意:委托的返回类型在泛型参数列表中是最后一个 。
14. 泛型方法可以在泛型 和非泛型以及结构和接口 中声明 。声明泛型方法时记住类型参数在方法名之后 ,方法参数列表之前 。如: public void PrintData<S> (S data) where S : Person {} 。
15. 在调用泛型方法时,编译器根据向方法传递的实参,可以推断出泛型方法的类型实参。可以省略类型参数和调用中 的尖括号。如: static List<T> MakeList<T> (T first, T second)
的声明,在实际调用时: List<string> list = MakeList<string> (“a”, “b”); 由于编译器可以推断实参的类型,所以调用可以简化为: List<string> list = MakeList (“a”, “b”) ; 。注意:泛型类型的推断只适用于泛型方法 ,不适用于泛型类 。
16. 扩展方法同样可以扩展泛型类 。要求和非泛型类一样:必须声明为 static ;必须是静态类的成员;第一个参数必须含有关键字 this ,后面跟要扩展的泛型类的名字。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/porscheyin/archive/2010/08/04/5789256.aspx