CLR via C#的第二章和第三章讲了大量的生成和部署.Net应用程序的知识,里面涉及到了大量我从来没接触过的知识,于是决定先跳到和自己现在工作联系比较紧密的第二部分,也就是类型的基础,回头再看什么强名称、程序集之类的内容。
.Net运行库要求所有的类型都最终从System.Object类型派生,所以,可以保证每个类型的每个对象都拥有一套最基本的方法,下面是System.Object提供的方法。
首先来说说它提供的公共实例方法:
Equals:如果两个对象具有相同的值,则它返回true。
GetHashCode:返回调用该方法的对象的值得一个哈希码。
ToString:默认情况下,返回的是该对象类型的完整名称(this.GetType().FullName)。然而通常需要重写这个方法,使它返回一个更有意义的字符串对象。
GetType:返回由Type派生的对象实例,它表示用于调用GetType对象的类型。返回的Type对象可以和反射类配合使用,从而可以获取与类型有关的元数据信息。需要注意的是这个方法是一个非虚方法,这样可以防止某个类重写该方法,并隐藏实际的类型,从而破坏类型的安全性。
然后说说它的受保护方法:
MemberwiseClone:这个非虚方法可以创建类型的一个新实例,并将新对象实例的各个字段设置成与this对象实例的字段完全一致。注意它返回的是对新实例的一个引用。
Finalize:在GC判断对象该作为垃圾收集之后,在对象的内存被实际回收之前,会调用这个虚方法。需要在回收之前执行一些清理工作的类型(比如SqlConnection、FileStream)应该重写这个方法。
CLR要求所有的对象都需要使用new操作符来创建对象,比如下面的语句:
Employee e=new Employee("ConstructorParam1");
接下来说说new操作符所具体做的事情:
1,首先它计算类型及其所有基类型(最高到System.Object,虽然它并没有定义自己的实例字段)中所定义的所有实例字段所需要的字节数。堆上的每一个对象都需要一些额外的成员——称为"类型对象指针(Type Object Pointer)"和"同步块索引(Synchronous Block Index)",这些成员将由CLR来管理对象,这些额外成员的字节数会加到对象大小上。
2,之后它从托管堆(Managed Heap)中分配制定类型所需的字节数,从而分配对象的内存,分配的所有字节都设为零。
3,然后初始化对象的"类型对象指针"和"同步块索引"成员。
4,调用类型的实例构造方法,向其传入在new调用中制定的任何实参(也就是"ConstructorParam1")。大多数编译器都在构造方法中自动生成代码来调用一个基类的构造方法。这样在调用每个类型的构造方法的时候,构造方法都负责初始化由这个类型定义的实例字段,因此最终会调用到System.Object的构造方法,不过这个方法仅仅是简单的返回,并不去做其他任何事情。
new在执行了上面的所有的操作后,会返回对新创建的对象的一个引用(或者是指针),在前面的实例代码中,这个引用会保存到变量e中,后者则具有Employee类型。
顺便说一下,与C++不同,new操作符并没有对应的delete操作符,也就是说,没有办法显式释放为一个对象分配的内存。不过CLR采用了垃圾回收机制(GC),它可以自动检测到一个对象不再被使用或访问,并自动释放对象的内存。
2008年11月4日星期二
订阅:
博文评论 (Atom)

没有评论:
发表评论