CLR via C#, 4th -- 【设计类型】 -- 第4章 类型基础

4.1 所有类型都从System.Object派生

“运行时”要求每个类型最终都从System.Object类型派生。

TABLE 4-1   P ublic Methods of  System.Object

Public Method

Description

Equals

Returns true if two objects have the same value. see the “Object Equality and Identity” section in Chapter 5

GetHashCode

Returns a hash code for this object’s value. A type should override this method if its objects are to be used as a key in a hash table collection, like  Dictionary. The method should provide a good distribution for its objects. It is unfortunate that this method is defined in  Object  because most types are never used as keys in a hash table; this method should have been defined in an interface. see the “Object Hash Codes” section in Chapter 5.

ToString

The default implementation returns the full name of the type ( this.GetType().FullName ). However, it is common to override this method so that it returns a String  object containing a representation of the object’s state.

GetType

Returns an instance of a  Type-derived object that identifies the type of the object used to call  GetType. The returned  Type object can be used with the reflection classes to obtain metadata information about the object’s type.

new操作符所做的事情:
1,计算类型及其所有基类型(一直到System.Object,虽然它没有定义自己的实例字段)中定义的所有实例字段需要的字节数。堆上每个对象都需要一些额外的成员,包括“类型对象指针”(type object pointer)“同步块索引”(sync block index),CLR利用这些成员管理对象。额外成员的字节数要计入对象大小。
2,从托管堆中分配类型要求的字节数,从而分配对象的内存,分配的所有字节都设为零(0)。
3,初始化对象的“类型对象指针”和“同步块索引”成员。
4,调用类型的实例构造器,传递在new调用中指定的实参。大多数编译器都在构造器中自动生成代码来调用基类构造器。每个类型的构造器都负责初始化该类型定义的实例字段。最终调用System.Object的构造器,该构造器什么都不做,简单地返回。

4.2 类型转换

CLR最重要的特性之一就是类型安全。在运行时,CLR总是知道对象的类型是什么。调用GetType方法即可知道对象的确切类型。由于它是非虚方法,所以一个类型不可能伪装成另一个类型。
使用C#的is和as操作符来转型
在C#语言中进行类型转换的另一种方式是使用is操作符。is检查对象是否兼容于指定类型,返回Boolean值true或false。注意,is操作符永远不抛出异常。

Object o = new Object();  
Boolean b1 = (o is Object);   // b1 is true.  
Boolean b2 = (o is Employee); // b2 is false.

if (o is Employee) {   
   Employee e = (Employee) o;  
   // Use e within the remainder of the 'if' statement.   
}

CLR核实X是否兼容于Y类型:如果是,as返回对同一个对象的非null引用。如果X不兼容于Y类型,as返回null。
as操作符的工作方式与强制类型转换一样,只是它永远不抛出异常-相反,如果对象不能转型,结果就是null。所以,正确做法是检查最终生成的引用是否为null.企图直接使用最终生成的引用会抛出System.NullReferenceException异常。

Object o = new Object();    // Creates a new Object object  
Employee e = o as Employee; // Casts o to an Employee  
// The cast above fails: no exception is thrown, but e is set to null.   
 
e.ToString();  // Accessing e throws a NullReferenceException.

4.3命名空间和程序集

命名空间对相关的类型进行逻辑分组,开发人员可通过命名空间方便地定位类型。
对于编译器,命名空间的作用就是为类型名称附加以句点分隔的符号,使名称变得更长,更可能具有唯一性。
编译器对待命名空间的方式存在潜在问题:可能两个(或更多)类型在不同命名空间中同名。
C# using指令的另一种形式允许为类型或命名空间创建别名。
C#编译器还提供了外部别名(extern alias)的功能,能通过编程来区分程序集而非仅仅区分命名空间。外部别名还允许从同一个程序集的两个(或更多)不同的版本中访问一个类型。
命名空间和程序集的关系
命名空间和程序集(实现类型的文件)不一定相关。特别是,同一个命名空间中的类型可能在不同程序集中实现。例如,System.IO.Filestream类型在MSCorLib.dll程序集中实现,而System.IO.FileSystemWatcher类型在System.dll程序集中实现。

4.4 运行时的相互关系

posted @ 2019-10-23 20:07  FH1004322  阅读(82)  评论(0)    收藏  举报