NET CLR via C#读书笔记 - 第六章 类型和成员基础
1 类型成员
1.1 类型成员一览
成员 | 说明 |
---|---|
常量 | 描述数据值恒定不变的符号。 与类型关联,不与类型实例关联。 |
字段 | 描述只读或者可读写的数据值。 字段可以是静态的(与类型关联),也可以是非静态的(与类型实例关联)。 |
实例构造器 | 将新对象的实例字段初始化的特殊方法。 |
类型构造器 | 将新对象的静态字段初始化的特殊方法。 |
方法 | 是用于查询或更改对象/类型状态的函数。 方法可以是静态的(与类型关联),也可以是非静态的(与类型实例关联)。 |
操作符重载 | 是一种特殊方法,定义了当操作符作用于对象时,对象应该如何进行操作。 |
转换操作符 | 是一种特殊方法,是定义如何显示或者隐式的将对象从一种类型转化为另一种类型的方法。 |
属性 | 设置和查询对象或者类型的逻辑状态,访问时保证状态不被破坏。 属性可以是静态的(与类型关联),也可以是非静态的(与类型实例关联)。 属性可以无参数,也可以有参数。 |
事件 | 静态事件允许类型向一个或多个静态/实例方法发送通知,非静态(实例)事件允许对象实例向一个或多个静态/实例方法发送通知。 事件包含两个方法:允许类型或者实例方法登记事件和注销对某一事件的关注。 |
类型 | 类型内部可以嵌套定义其它类型。 |
演示代码如下:
using System;
public sealed class Demo{
private class SubDemo{} //嵌套类型
private const int c_SomeConstant = 0; //常亮
private readonly string m_SomeString = ""; //只读字段
private static int s_SomeStatic = 1; //静态可读可写字段
private int s_SomeUnStatic = 2; //可读可写字段
static Demo(){} //类型构造器
public Demo(){} //实例构造器
public Demo(int i){} //带参数的实例构造器
private void Func_UnStatic_1(){} //实例方法
public static void Func_Static_1(){} //静态方法
//实例属性
public int Some_attr_1{
get{return 0;}
set{}
}
//实例有参属性(索引器)
public int this[string s]{
get{return 0;}
set{}
}
//实例事件
public event EventHandler SomeEvent;
}
2 类型的可见性
public : 全局可见,不仅仅对定义类型所处的程序集可见,在其它程序集中也可见。
internal: 对定义类型所处的程序集可见,在其它程序集中不可见。
3 类型成员的可访问性
CLR术语 | C#术语 | 说明 |
---|---|---|
Private | private | 成员只能由定义类型或者任何嵌套类型访问。 |
Family | protected | 成员只能由定义类型,任何嵌套类型和任意程序集中的派生类型访问。 |
Family and Assembly | 不支持 | 成员只能由定义类型,任何嵌套类型和同一程序集中的派生类型访问。 |
Assembly | internal | 成员只能由定义程序集中的类型访问。 |
Family or Assembly | internal | 成员可由任意嵌套类型,任何派生类型以及定义程序集中的任何类型访问。 |
Public | public | 成员任何类型访问。 |
4 类型的分类
4.1 静态类
静态类不可实例化,使用static关键字进行定义,静态类的作用就是组合一组相关的操作,static只能作用于类(class),不能作用于结构(struct)。
静态类有以下限制:
静态类限制 |
---|
静态类必须从System.Object派生,从其它类派生没有任何意义,因为静态类不能实例化,而继承只适用于对象。 |
静态类不能实现任何接口,只有类的实例才可以调用类的接口方法,而静态类无法实例化。 |
静态类只能定义静态成员(字段,方法,属性,事件),定义实例字段都会编译报错。 |
静态类不能作为字段,方法参数和局部变量使用。检测到以上用法,在编译时,编译器会编译报错。 |
4.2 分部类,结构和接口
类,结构和接口的源代码定义可能在某些情况下需要分散到多个源代码文件中,因此出现了分部类,结构和接口,使用partial定义分部类,结构和接口。
分部类,结构和接口应用于如下情况:
1、源代码控制:便于团队合作
2、将类/接口/结构分解为不同的逻辑单元:便于代码阅读和功能删减和添加
3、代码拆分:便于分离类型中稳定和不稳定的部分
5 组件,多态和版本控制
5.1 C#关键字对其组件版本控制的影响
C#关键字 | 作用于类型 | 作用于方法/属性/事件 | 作用于常量/字段 |
---|---|---|---|
abstract | 表示不能构造该类型实例。 | 表示为了构造派生类型的实例,派生类型必须重写和实现该成员。 | 不允许 |
virtual | 不允许 | 表示可由派生类型重写。 | 不允许 |
override | 不允许 | 表示派生类型正在重写基类型成员。 | 不允许 |
sealed | 该类型不能用作基类。 | 表示成员不能被派生类重写,只能将该关键字用于重写虚方法的方法。 | 不允许 |
new | 表示该类型与基类中相似成员无任何关系 | 表示该方法/属性/事件与基类中相似成员无任何关系 | 表示该常量/字段与基类中相似成员无任何关系 |
5.2 CLR调用虚方法简述
5.2.1 call和callvirt
C#中提供了call和callvirt两种调用指令的方式,其中call可以执行静态,实例和虚方法,callvirt只能执行实例和虚方法,不能调用静态方法。
call在执行指令时,假定变量类型不为null,call通常以非虚方式调用虚方法。
callvirt在执行指令时,如果callvirt调用的是虚方法,CLR会检查调用者的实际类型,以多态方式调用虚方法,这种方式必须保证变量不为null,所以CLR会检查变量类型是否为null,为null则抛出异常NullReferenceException,不为null才会正确调用。
以上内容为对《NET CLR via C#(第四版)》第六章内容的阅读笔记,只记录其中核心部分内容,书中还仔细描述了如何合理使用类型的可见性和可访问性,对类型进行版本控制的虚函数的处理等话题,如需要详细阅读请自行查阅本书第六章内容。