3.1应用程序启动
应用程序:具有入口点的程序集
当应用程序运行时,将创建新的应用程序域,同一台计算机可能会同时运行着同一个应用程序的若干实例,则每个实例都有各自的应用程序域;
应用程序域通过作为应用程序状态的容器使应用程序得以隔离,应用程序域作为应用程序中和它使用的类库中所定义的类型的容器和边界;
同一个类型若被加载到不同的应用程序域,就成为各自堵路的客体,由它们在各自应用程序域中产生的实例同样不可直接共享;
至于如何处理程序域的创建和销毁,各实现方法可以按具体情况确定自己的策略或机制。
应用程序启动:在执行环境调用指定的方法(称为程序的入口点)时发生,这个入口点方法总是被命名为Main,可以具有下列签名之一:
入口点也可以选择是否包含参数,若有则参数类型必须为string[],那时执行环境会创建并传递一个包含命令行参数的string[]参数,这些命令行参数是在启动应用程序时指定的;string[]参数永远不能为null,若果没有指定命令行参数,它的长度为零。
注:
1.C#虽然支持方法重载(方法名一样,参数不同的方法),但在一个程序内,没有任何类或结构可以包含一个以上的名为Main的方法,这是因为Main的定义限制它只能用做应用程序的入口,允许使用Main的其他重载版本,前提是它们具有一个以上的参数或唯一参数类型不是string[]。
2.应用程序可由多个类或结构组成,在这些类或结构中,可能会有若干个拥有自己的Main方法,这种情况必须利用某种外部机制(如命令行编译器的选项)来指定哪个Main方法作为入口点。
3.在C#中同样存在访问性限制,应用程序入口是作为特殊情况存在的,执行环境不管入口什么访问类型,都可以访问(就这么强势)!
3.2应用程序终止
应用程序终止,将控制权返回给执行环境。
刚才知道入口方法的返回类型可以是int,也可以是void;若为int,则返回的值作为应用程序的终止状态代码,这个终止状态代码是用来允许与执行环境进行关于应用程序状态(成功或失败)的通信;若为void,到达终止该方法的"}"或执行不带表达式的return时,会产生终止状态代码0。
还有在应用程序终止之前,将调用还没有被垃圾回收的对象的析构函数,除非这类清理功能被设置为停止使用。
3.3声明
C#程序使用声明定义构成程序的元素。C#程序是用命名空间组织起来的,一个命名空间可以包含类型声明和嵌套的命名空间声明;
类型声明用于定义类、结构、接口、枚举和委托,即一个类型声明中可以使用哪些类型作为成员,取决于该类型声明的形式;
声明所定义的名称属于它自己所属的那个声明空间,除非是重载成员,否则存在两个以上声明相同名称的成员会发生编译错误,也不能存在不同类型的同名成员;
有若干种不同类型的声明空间:
1.在程序的所有源文件中,命名空间成员声明若没有至于任何一个命名空间声明之下,就称为全局声明空间;
2.在程序的所有源文件中,一个命名空间成员声明在命名空间声明中具有相同的完全限定的命名空间名称,就属于一个组合声明空间;
3.基类和类、基接口和接口的声明空间无关,所以在派生类或接口声明和继承成员的声明同样时,我们称是隐藏了继承成员;
4.每个枚举声明创建一个新的声明空间,名称通过枚举成员声明引入此声明空间;
5.每个块为局部变量和常量创建一个不同的声明空间,在嵌套块中不可能声明与封闭它的块中的局部变量同名的局部变量;
3.4成员
命名空间和类型都具有成员,通常使用限定名来访问实体的成员,限定名以该实体的引用开头,后面跟个"."标记,再接成员名称;
类型的成员是该类型中声明的,也可以从该类型的基类继承的;除基类的实例构造函数、静态构造函数和析构函数外,都可以继承;在派生类或许有不能访问已经被继承的成员,原因不是其声明的可访问性不让访问,就是被自身的声明隐藏了。
3.4.1命名空间成员
命名空间和类型若没有封闭它的命名空间,则属于全局命名空间的成员;在某命名空间声明的命名空间和类型是该命名空间的成员;命名空间没有访问限制,命名空间名称始终是可公开访问的。
3.4.2结构成员
结构的成员是结构组声明的成员和从object类继承的成员;简单类型的成员直接对应于结构类型的成员,此简单类型正式该结构的化名:
3.4.3枚举成员
枚举成员是在枚举中声明的常数和从System.Enum类继承的成员。
3.4.4类成员
类成员是在类中声明的成员和从该类的基类(object除外,因为它没有基类)继承的成员,还是那句话,除基类的实例构造函数、静态构造函数和析构函数外,都可以继承;
再说一次,类声明可以包含以下对象的声明:常数、字段、方法、属性、事件、索引器、运算符、实例构造函数、静态构造函数、析构函数和类型;
3.4.5接口成员
接口成员是在接口中和该接口所有基类中声明的成员,以及从object类继承的成员。
3.4.6数组成员
数组成员是从System.Array类继承的成员。
3.4.7委托成员
委托成员是从System.Delegate类继承的成员。
3.5成员访问
成员的声明可用于控制对该成员的访问,成员的可访问性是由该成员的可访问性声明和直接包含它的那个类型的可访问性结合起来控制的。
3.5.1已声明可访问性
当成员不包含访问修饰符时,声明发生处的上下文会为该成员选择一个默认的修饰符。
命名空间隐式的是public,且命名空间声明中不允许使用访问修饰符;
在编译单元或命名空间声明的类型可以为public、internal,默认是internal;
类成员可以是5种的任意一个,默认是private;
结构成员可以是public、internal、private,默认是private,;
接口成员、枚举成员都是隐式地public,且在接口/枚举成员声明种不允许使用访问修饰符。
总结:未嵌套在其他类型中的被称为顶级类型,它们只能具有internal
或public
可访问性,这些类型的默认可访问性为internal;
3.5.2可访问域
成员的可访问域由程序文本节组成(可能是不连续的),从那里可以访问该成员。预定义类型的可访问域是无限制的。
程序——程序文本:定义为包含在该程序的所有源文件中的全部程序文本;
类型——程序文本:定义为包含在该类型的"类体"、"结构体"、"接口体"或"枚举体"的开始和结束("{"和"}")标记之间的全部程序文本。
下面这个图是解释以下上面这个图,下面是草稿图,P表示程序,F表示引用P的其他程序,T表示顶级类型,M表示T中的成员
3.6签名和重载
方法、实例构造函数、索引器和运算符是由它们的签名来刻画的:
方法签名:由方法的名称+它的每一个参数的类型和种类(值、引用或输出)组成,不包括返回类型和params修饰符;
实例构造函数签名:由它的每一个参数的类型和种类(值、引用或输出)组成,同样不包括params修饰符;
索引器签名:由它的每一个参数的类型组成,不包含元素类型;
运算符签名:由运算符的名称+它的每一个参数的类型组成,不包含结果类型。
签名是对类、结构和接口的成员实施重载的机制:
方法重载允许类、结构或接口用同一个名称声明多个方法,条件是它们的签名在该类、结构或接口中是唯一的;
实例构造函数重载允许类或结构声明多个实例构造函数,条件是它们的签名在该类或结构中是唯一的;
索引器重载允许类、结构或接口声明多个索引器,条件是它们的签名在该类、结构或接口中是唯一的;
运算符重载允许类或结构用同一个名称声明多个运算符,条件是它们的的签名在该类或结构中是唯一的。
注:ref和out参数修饰符也是签名的组成部分,也就说F(int)和F(ref int)都2个不同的签名。