NET框架程序设计-第4章类型基础
4.1 所有类型的基类型:System.Object
CLR 要求每个类型最终都要继承自 System.Object 类型。
两种类型定义:
1)隐式继承
//隐式继承 Object
class Employee{}
2)显式继承
class Employee:System.Object{}
System.Object 主要的公有实例方法:
公有方法 | 描述 |
---|---|
Equals | 如果两个对象具有相同的值,方法将返回 true。 |
GetHashCode | 方法返回对象的值的散列码。 |
ToString | 默认情况下,方法返回类型全名(this.GetType().FullName.ToString())。但是,还有一种常见的做法是重写该方法使其返回一个表示对象状态的字符串。例如,.NET 框架中的一些核心类型(如 Boolean 和 Int32)就重写该方法,使其返回表示它们的值的一个字符串。另一种常见的做法是重写该方法以用于调式目的:我们可以通过调用它来得到一个表示对象字段值的字符串。注意 ToString 通常会利用与调用线程相关联的 CultureInfo。 |
GetType | 方法返回一个类型为继承自 Type 的对象实例,其标识了该方法所属对象的类型。返回的 Type 对象可以和反射类一起使用来获得类型的元数据信息。 |
System.Object 主要的受保护方法:
受保护方法 | 描述 |
---|---|
MemberwiseClone | 这是一个非虚方法,它创建一个新的类型实例,并将其字段设置为和 this 对象的字段相同,最后返回新创建的实例引用。 |
Finalize | 这是一个虚方法,当垃圾收集器判定某个对象为可回收的垃圾时,垃圾收集器会在对象内存被回收之前调用此方法。那些内存回收时需要资源清理的类型应该重写该方法。 |
创建一个对象:
Employee e = new Employee("ConstructorParaml");
new 操作符所执行的工作:
-
1、从托管堆(managed heap)中分配指定类型所需数量的字节来作为存储其对象的内存空间。
-
2、初始化对象的附加成员(overhead members)。每一个对象实例都有两个附加成员。其中第一个成员为指向类型方法表的指针,第二个成员为 SyncBlockIndex。(CLR 使用该字段来进行线程同步控制。该字段的某些位还用作垃圾收集时的标记。另外 FCL 中 System.Object 类型默认的 GetHashCode 方法也用到了该字段)。CLR 使用这两个成员来管理对象实例。
-
3、传入 new 操作符中指定的参数,调用类型的实例构造器。虽然大多数语言在编译构造器时都会要求它们调用基类型中相应的构造器。但 CLR 本身没有这样的要求。
4.2 类型转换
隐式转换:可以将对象转换为其任何一个基类型,因为转换为基类型被认为是安全的隐式操作。
显示转换:将对象转换为它的任何派生类型时,C# 要求进行显示转型。
class Employee{}class App{public static void Main(){//这里不需要转型Object o = new Employee();//这里需要转型Employee e = (Employee)o;}}
显示转换的安全性:
class Employee{}class Manager : Employee{}class App1{public static void Main(){Manager m = new Manager();PromoteEmployee(m);DateTime newYears = new DateTime(2001, 1, 1);//CLR 将禁止执行转型操作,并抛出一个 System.InvalidCastException 异常。PromoteEmployee(newYears);}public static void PromoteEmployee(object o){//1、编译并不知道对象 o 引用的实际类型。//2、所以编译器允许代码通过编译。//3、在运行时(进行转型操作时),CLR 获取到o引用的类型//4、检查对象 o 是否为 Employee。Employee e = (Employee) o; }}
4.2.1 使用 is 和 as 操作符转型
is: 检查对象的类型,如果类型兼容,则返回 true,否则,返回 false;
if(o is Employee){//此处再进行一次检查对象的类型;Employee e = (Employee)o;}
as: 执行转换,若类型兼容,则返回要转换对象的类型,否则,返回 NULL;
Employee e1 = o as Employee;if(e1 != null){}
若转换的类型为 null ,抛出异常:
Object o = new object();Employee e = o as Employee;e.ToString();//若e为空,访问 e 将导致抛出异常 NullReferenceException
s 和 as 的用法情况:
- is 适合用在只检查对象的类型,若吗,若满足 if 条件,则在 if 语句内最好不出现对象类型的转换行为,否则会出现二次检查对象类型的行为。
- as 适用于既要检查对象类型,又要引用对象转换的类型;
4.3 命名空间与程序集
例子:
class Test{public void fun(){System.IO.FileStream fs = new System.IO.FileStream("test.txt", System.IO.FileMode.Open);System.Collections.Queue q = new System.Collections.Queue();}}
优化:
using System.IO;
using System.Collections;class Test{public void fun(){FileStream fs = new FileStream("test.txt", System.IO.FileMode.Open);Queue q = new Queue();}}
二义性
例子:微软和 Wintellect 公司的组件都有一个名为 Widget 的类型。
using Microsoft;
using Wintellect;
class Test{public void fun(){Widget w = new Widget();//具有二义性Wintellect.Widget w2 = new Wintellect.Widget(); //消除二义性}}
进一步消除二义性的优化:
using Microsoft;
using Wintellect;
//定义命名空间的别名using WintellectWidget = Wintellect.Widget;
class Test{public void fun(){WintellectWidget w = new WintellectWidget();}}