1、继承
如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和override,派生类方法就会隐藏基类方法。
从派生类中调用方法的基类版本:base.<MethodName>()。
允许把类和函数声明为abstract。抽象类不能实例化,而抽象函数不能直接实现,必须在非抽象的派生类中重写。
密封类和密封方法,被类和方法声明为sealed。对于类,表示不能继承该类,对于方法,标识不能重写该方法。
如果基类不希望有重写的方法或属性,就不要把它声明为virtual。
总是最先调用的正式基类的构造函数。派生类的构造函数可以在执行过程中调用它可以访问的任何基类的方法,属性和任何其他成员。
base和this关键字是调用另一个构造函数时允许使用的唯一关键字,其他关键字都会产生编译错误。
接口只能包含方法,属性,索引器和事件的声明。
2、泛型
从值类型转换为引用类型称为装箱,将引用类型转换为值类型称为拆箱。
装箱和拆箱操作很容易实用,但性能影响比较大。
List <T>类不使用对象,而是在使用时定义类型。
泛型的另一个特性是类型安全。List<T>中,泛型T定义了允许使用的类型。
泛型允许更好地重用二进制代码。可以定义一次,并且可以用许多不同的类型实例化。
JIT编译器把泛型类型编译为本地代码时,会给每个值类型创建一个新类。引用类型共享一个本地类的索引相同的实现代码。
泛型类型的名称T,如果泛型有特定的要求,或者使用了两个或多个泛型类型,就应给泛型类型使用描述性的名称。
通过default关键字,将null赋予引用类型,将0赋予值类型。
如果泛型类需要调用泛型类型中的方法,就必须添加约束。
T类定义一个约束,TDocumet类型必须实现IDocument接口。where字据实现了约束。
泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中。
使用泛型可以定义接口,在接口中定义的方法可以带泛型参数。
同一个接口常常存在比较老的非泛型版本。
非泛型版本需要强制类型转换到特定的类型,实现泛型版本时,不再需要将object的类型强制转换为Person。
参数类型是协变的。现在可以传递派生自Shape基类的任意对象。
方法的返回类型是抗变的。当方法返回一个Shape时,不能把它赋予Rectangle。
可空的值类型int? x2。
定义泛型方法, Swap<T>()方法把T定义为泛型类型。