zoukankan      html  css  js  c++  java
  • 第4章 类型基础 -- 4.1 所有类型都从System.Object派生

    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采用了垃圾回收机制,能自动检测到一个对象不再被使用或访问,并自动释放对象的内存。

  • 相关阅读:
    MongoDB 释放磁盘空间 db.runCommand({repairDatabase: 1 })
    RK 调试笔记
    RK Android7.1 拨号
    RK Android7.1 移植gt9271 TP偏移
    RK Android7.1 定制化 itvbox 盒子Launcher
    RK Android7.1 双屏显示旋转方向
    RK Android7.1 设置 内存条作假
    RK Android7.1 设置 蓝牙 已断开连接
    RK Android7.1 进入Camera2 亮度会增加
    RK 3128 调触摸屏 TP GT9XX
  • 原文地址:https://www.cnblogs.com/ethanwill/p/5770984.html
Copyright © 2011-2022 走看看