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

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

由于所有类型最终都从System.Object派生,所以每个类型的每个对象都保证了一组最基本的方法。

System.Object类提供了如下表所示的公共实例方法:

表4-1 System.Object的公共方法
Equals 若两个对象具有相同的值,就返回 true 。详情请参考"对象相等性和同一性"
GetHashCode  

返回对象的值的哈希码。如果某个类型的对象要在哈希表集合(比如 Dictionary )中作为键使用,类型应重写该方法。

方法应该为不同的对象提供良好分布(是指针对所有输入,GetHashCode生成的哈希值应该在所有整数中产生一个随机的分布。 --译注)。

将这个方法设计到 Object 中并不恰当。大多数类型永远不会在哈希表中作为键使用:该方法本该在接口中定义。

ToString

默认返回类型的完整名称(this.GetType().FullName)。但经常重写该方法来返回包含对象状态表示的 String 对象。 例如,核心类型(如 Boolean 和 Int32 )重写该方法来返回它们的值的字符串表示。

另外,经常处于调试的目的而重写该方法:调用后获得一个字符串,显示对象各字段的值。事实上,Microsoft Visual Studio的调试器会自动调用该函数来显示对象的字符串表示。

注意,ToString 理论上应察觉与调用线程关联的 CultureInfo 并采取相应行动。 “字符、字符串和文本处理”将更详细地讨论ToString

GetType  

返回从 Type 派生的一个类型的实例,指出调用 GetType 的那个对象是什么类型。

返回的 Type 对象可以和反射类配合,获取与对象的类型有关的元数据信息。反射将在“程序集加载和反射”讨论。

GetType 是非虚方法,目的是防止类重写该方法,隐瞒其类型,进而破坏类型安全性。

此外,从System.Object派生的类型能访问如表4-2所示的受保护方法。

表4-2 System.Object的受保护方法
MemberwiseClone 

这个非虚方法创建类型的新实例,并将新对象的实例字段设与 this 对象的实例字段完全一致。

返回对新实例的引用(作者在这段话里引用了两种不同的“实例”。一种是类的实例,也就是对象;另一种是类中定义的实例字段。

所谓“实例字段”,就是指非静态字段,有时也称为“实例成员”。简单地说,实例成员属于类的对象,静态成员属于类。 --译注)。

Finalize 

在垃圾回收器判断对象应该作为垃圾被回收之后,在对象的内存被实际回收之前,会调用这个虚方法。

需要在回收内存前执行清理工作的类型应重写该方法。

“托管堆和垃圾回收”会更详细地讨论这个重要的方法。

CLR要求所有对象都用 new 操作符创建。以下代码展示了如何创建一个 Employee 对象:

Employee employee = new Employee("ConstructorParam1");

以下是 new 操作符所做的事情:

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

new 执行了所有这些操作之后,返回指向新建对象的一个引用(或指针)。在前面的示例代码中,该引用保存到变量employee中,后者具有 Employee 类型。

Btw, 没有和 new 操作符对应的 delete 操作符;换言之,没有办法显式释放已为对象分配的内存。CLR采用了垃圾回收机制,能自动检测到一个对象不再被使用或访问,并自动释放对象的内存。

第4章 类型基础 -- 4.1 所有类型都从System.Object派生的更多相关文章

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

    "运行时"要求各个类型最终都从 System.Object 派生.(显示继承/隐式继承) 提供公共方法(public): Equals 判断两个对象相等,true 表示相等. Ge ...

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

  3. NET CLR via C#(第4版)第4章 类型基础

    本章内容: 1 所有类型都从System.Object派生 2 类型转换 3 命名空间和程序集 4 运行时的相互关系   本章讲述使用类型和CLR时需掌握的基础知识.具体地说,要讨论所有类型都具有的一 ...

  4. 重温CLR(三)类型基础

    所有类型都从System.Object派生 “运行时”要求每个类型最终都要从System.Object类型派生.也就是说,一下两个类型的定义完全一致. //隐式派生自Object class Empl ...

  5. NET基础(1):类型基础

    所有类型都从System.Object 派生,‘运行时’要求每个类型都从System.Object类派生,也就是说,以下两个类型定义完全一致: //隐式派生字Object class Employee ...

  6. 【C#进阶系列】04 类型基础

    关于System.Object 所有类型都从System.Object派生而来. System.Object的公共方法中ToString()一般是返回对象的类型的全名,只有Int32这些类型将其重写后 ...

  7. CLR Via C#: 类型基础

    所有类型都从System.Object派生 一下两个类型定义是完全一致的 class Employee { } class Employee : System.Object { } 由于所有类型最终都 ...

  8. 《C#从现象到本质》读书笔记(二)第2章 C#类型基础(上)

    <C#从现象到本质>读书笔记第二篇 第2章 C#类型基础(上) 类型指的是集合{类,结构,接口,枚举,委托}中的任意一个成员.任何拥有某类型的值(value)称为某类型的一个实例(inst ...

  9. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

随机推荐

  1. Hadoop常见的45个问题解答

    (大讲台:国内首个it在线教育混合式自适应学习) 1.Hadoop集群可以运行的3个模式 单机(本地)模式 伪分布式模式 全分布式模式 2.  单机(本地)模式中的注意点? 在单机模式(standal ...

  2. RS232转RS485电路图分析

    在电子发烧友网站上,看到RS232转RS485的一个电路图,如下图所示.元件主要是HN232CP和MAX485CPA,也就是TTL转232电路和TTL转485电路的结合体.可是这个电路却不好分析,几经 ...

  3. swift-UILabel

    // Mark: 2. 创建label private func creatLabel(title: NSString)->UILabel{ /// 创建label let titleL = U ...

  4. poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)

    http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS   Memory Limit: 65536K Total Submi ...

  5. 一个简单的php分页类代码(转载)

    入门级php分页类 原文地址:http://www.xfcodes.com/php/fenye/3608.htm 时间:2015-12-16 20:52:00来源:网络 php分页类. 复制代码代码如 ...

  6. 对C语言中sizeof细节的三点分析

    转自对C语言中sizeof细节的三点分析 1.sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行. 那么如果编程中验证这一点呢?ps:这是前两天朋友淘宝面试 ...

  7. Cocos2d-x 3.2编译Android程序错误的解决方案

    最近的升级Cocos2d-x 3.2正式版.iOS不管是什么程序编译问题,使用结果cocos compile -p android编译APK计划.结果悲剧,出现以下错误. Android NDK: I ...

  8. 还是编码 汉字(GB2312和GBK)的ASCII码对照表

    GB2312和GBK每一个汉字由2个字节组成,这2个字节的ASCII码大小分别是:gb2312: high8 = 0xa1-->0xfe (161 - 254)low8 = 0xa1--> ...

  9. LCD 和 LED 的区别?

    http://sxlecd.blog.163.com/blog/static/131722380200911810564930/

  10. 从 C++ 到 Qt(命令行编译)good

    从 C++ 到 Qt 转载自:http://hi.baidu.com/cyclone/blog/item/8f8f08fa52d22f8758ee9006.html Qt 是 C++ 的库,Qt在an ...