1. 类型基础
1.1. 基类型System.Object
CLR要求所有的对象都要用new操作符来创建,new操作符所执行的工作:
1) 从托管堆中分配指定类型所需的内存空间;
2) 初始化对象的附加成员:类型方法表指针和SyncBlockIndex;
3) 传入new操作符中指定的参数,调用类型的实例构造器;
在new完成上述操作后,将返回一个指向新创建对象的引用。CLR中没有和new对应的delete操作符,分配的内存由垃圾回收器负责。
1.2. 类型转换
CLR在运行时总能知道一个对象的类型,也可以通过调用GetType方法来得到对象的准确类型。GetType方法为非虚方法,因此不可能利用它来篡改一个类型的信息。
CLR允许将对象转换为其原来的类型或者它的任何一个基类型。例如:C#不许要任何特殊的语法就可以将对象转换为任何一个基类型,转换为基类型被认为是安全的隐式操作。CLR会检查转型操作以确保总是将对象转型为它的实际类型,或者它的任何基类型。
1) IS操作符检查对象是否和给定的类型兼容,并返回判断结果。IS操作符不会抛出异常。如果对象引用为NULL,那么IS操作符总是返回false;
2) AS操作符检查引用对象是否和给定的类型兼容,如果兼容则返回一个同一对象的引用,否则返回NULL。AS操作符不会抛出异常;
If ( o is Employee )
Employee e = (Employee)o;
上面的代码,CLR实际上对对象的类型检查了两次。Is操作符首先检查o所引用的对象是否和Employee兼容。如果兼容,if语句内在执行转换时CLR又会检查o是否为一个指向Employee的引用。为了提高性能C#提供了as操作符。
Employee e = o as Employee;
If ( e != null ) { … }
上面的代码中只检查了一次对象的类型,如果兼容as则返回一个指向同一对象的非空指针,否则返回null。检查e是否为null要比类型检查的效率高。
1.3. 命名空间与程序集
命名空间允许我们对相关类型进行逻辑上的组织。C#的using指示符会指示编译器试着在类型名上添加不同的前缀,直到找到一个匹配为止。
当查找一个类型的定义时,编译器必须被告知到哪些程序集中进行查找。编译器将扫描它知道的所有程序集来查找类型的定义。C#编译器默认情况下会自动在MSCorLib.dll程序集中进行查找。
C#还提供了另一种形式的using指示符允许我们为一个类型或者命名空间创建另外的别名。例如:
Using WintellectWidget = Wintellect.Widget;
但C#的using指示符仅支持命名空间,没有提供任何指定程序集的方式。命名空间和程序集并非必然相关,多个属于同一命名空间中的类型可能被实现在多个程序集中,一个程序集也可以包含位于不同命名空间中的类型。