读 CLR-via-C# 总结之六 类型和成员基础

类型和成员基础

6.1类型的各种成员

  1. 常量:就是指出数据恒定不变的一个符号。通常与类型想关联,而不是对象。所以从逻辑上讲,常量始终是静态成员。字段:表示一个只读或者可读/可写的数据值。可以是静态的,也可以是实例,被认为是对象状态的一部分。本书建议将字段声明为私有字段,防止类型或者对象的状态被类型外部的代码破坏。实例构造器:是将新对象的实例字段初始化为良好初状态的一个特殊方法。类型构造器:是将类型的静态字段初始化为良好初始状态的一个特殊方法。方法:方法是一个特殊的函数,作用是更改或查询一个类型或对象的状态。作用于类型时,成为静态方法。作用于对象时是实例方法。方法一般可以对类型或对象的字段进行读写操作。操作符重载:它定义了将一个特定的操作符作用于对象时,应该如何操作这个对象。转换操作符;属性:用其可以使用一种简单的,字段风格的语法来设置或查询类型或对象的部分逻辑状态,同时保证状态不被破坏。属性可以是没有参数的,也可以是多个参数的。事件:利用静态事件,一个类型可以向一个或多个静态或实例方法发送通知。而利用实例事件,一个对象可以向一个或多个静态或实例方法发送通知。提供事件的类型或对象的状态发生改变,通常就会引发事件。事件包含两种方法,允许静态或实例方法登记或注销对该事件的关注。除了这两个方法,事件通常还使用一个委托字段来维护已登记的方法集。类型:类型可以定义嵌套于其中的其它类型。通常用这个办法将一个大的,复杂的类型分解成更小的构建单元,以简化实现。
  2. 无论使用什么编程语言,编译器都必须能处理你的代码,使之生成元数据和IL代码,而元数据的格式都是完全一致的。元数据是所有语言都生成和使用的公共信息,正是因为有了元数据,用一种语言写的代码才能无缝访问用另一种语言写的代码。元数据是整个Microsoft .NET Framework开发平台的关键,它实现了编程语言,类型,和对象的无缝集成。

 

6.2类型的可见性

  1. 在文件范围中定义类型时,可以将类型的可见性指定为public或者internal后者只在本程序集中可见。如果不指定类型的看见性,默认为范围小的那个internal。
  2. 友元程序集:在构建程序集时,可以使用System.Runtime.CompilerService命名空间中定义一个名为InternalsVisibleTo的attriute来标明它认为是”友元”的其他程序集,这个attriute要获取一个字符串参数,这个字符串参数标识了友元程序集的名称和公钥。使用友元标识的internal程序集可以让其它程序集访问。

 

6.3成员的可访问性

  1. 限制性从大到小依次为:private(成员只能有定义类型和任何嵌套类型中的方法访问);protected(成员只能由继承类访问);internal(成员只能由本程序集中的方法访问);public(任何地方访问)当然任何成员想被别人访问到,都必须在一个可见的类型中定义。如果没有显示标识,则默认为限制性最大的即:private。
  2. CLR要求接口类型的成员都必须是public可访问性,C#编译器知道这一点,因此禁止开发人员显示指定接口成员的可访问性,编译器会自动将所有成员的访问性设置为public.
  3. 一个派生类型重写在它的基类型中定义的一个成员时,C#编译器要求原始成员和重写成员具有相同的可访问性。但是这只是C#语言本身的一个限制,而不是CLR的。从一个基类派生时,CLR允许放宽成员的可访问性限制,但不允许收紧。

 

6.4  静态类

1.有一些永远不需要实例化的类:Console;Math;Environment;ThreadPool类。要用static关键字定义不可实例化的类。这个关键字只能作用于类,不能作用于结构(值类型)。这是因为CLR总是允许值类型实例化。

2.C#编译器对静态类进行了如下的限制:必须从基类System.Object中派生;不能实现任何接口;只能定义静态成员,任何实例成员都会导致编译器报错;静态类不能作为字段,方法参数,或局部变量使用,因为它们都代表了一个实例的变量,而这是不允许的。

3.使用static关键字定义一个类,将导致C#编译器将该类同时标记为abstract(静态)和sealed(密封)。另外,编译器不会在类型中生成一个实例构造方法。

 

6.5 分部类 结构 接口

1.这个功能是由编译器提供的,CLR并不知道这些内容。所以被拆分的最终会进行合并。使用partial这个关键字告诉C#编译器,一个类,结构,接口的定义源码可能要分散到一个或者多个源代码文件中。这个做的原因有:源代码控制:将源代码分散到多个源代码文件中,每个文件又可以单独签出,可以使多个程序员能同时编辑类型;在同一个文件中,将一个类或结构分解成不同的逻辑单元。对一个完整的类型进行拆分,然后,在分部类型的每个部分,都实现一个功能,并配以它的全套字段,属性,事件等。与此同时,可以方便的将一个分布类型注释掉,这样可以方便地从类中删除一个完整的功能,代之以另一个实现;代码拆分。

 

6.6组件 多态和版本控制

  1. 组件软件编程(Component Software Programming),其中组件有以下特点:组件(.NET称为程序集)有”已经发布”的意思;组件有自己的标识(名称,版本,语言文化,密钥);组件永远维持自己的标识(程序集永远不会静态链接到另外一个程序集中,.NET总是使用动态链接);组件清楚的指明它所依赖的组件(引用元数据表);组件要文档化它的类和成员;组件必须指定它要求的安全权限;组件要求发布一个在任何”维护版本”中都不会改变的接口。
  2. 在.NET中版本号分为四个部分:主版本号,次版本号,内部版本号,和修订号。前两者通常代表程序集一个连续的,稳定的功能集,而后两者代表对这个功能集的一次维护。
  3. 将某个组件中定义的一个类型作为另一个组件中的一个类型的基类使用时,变会发生版本控制的问题。如果基类的版本低于派生类,派生类的行为也会改变,这可能造成行为失常。
  4. 方法代表在类型或者类型实例上执行某些操作的代码,任何方法都有一个名称,签名,返回值。两个同名方法可以根据参数类型,和返回值类型的不同进行区分。
  5. 编译器在编译代码时,会在生成的程序集的方法定义表中写入记录项,每个记录项都用一组标志(flag)来指明方法是实例方法,虚方法,还是静态方法。如果写代码来调用这些方法,那么生成调用代码的编译器会检查方法定义的标志(flag),判断应该如何生成IL代码来正确的调用方法。CLR提供了两个指令:call(调用静态:调用静态方法时,必须指明哪个类型。:实例:必须指定引用了一个对象的变量,虚方法)和callvirt(实例,虚方法):指令在调用时,会验证调用的变量是否为null,如果是的话会抛出异常。
  6. 当类处于非密封状态时,只要它的任何数据字段或者在内部对这些字段进行的处理方法是可以访问的,而且不是私有的,派生类就能访问和更改基类的状态。另外,派生类即可重写基类的虚方法,也可以直接调用这个虚方法在基类的实现。密封类的缺点在于,它会对类型的用户照成巨大的不方便如:在派生类添加一些额外的字段或状态信息时。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值