zoukankan      html  css  js  c++  java
  • NET CLR via C#(第4版)第4章 类型基础

    本章内容:
    1 所有类型都从System.Object派生
    2 类型转换
    3 命名空间和程序集
    4 运行时的相互关系
     
    本章讲述使用类型和CLR时需掌握的基础知识。具体地说,要讨论所有类型都具有的一组基本行为。
    讨论类型安全性、命名空间、程序集、以及如何将对象从一种类型转换成另一种类型。
    本章最后会解释类型、对象、线程栈和托管堆在运行时的相互关系。
     
    4.1 所有类型都从System.Object派生
    CLR要求每个类型最终都从System.Object类型派生。从而确保类每个对象都具备一组最基本的方法。
    [公开方法]
    Equals
    GetHashCode
    ToString
    GetType
    [受保护方法]
    MemberwiseClone
    Finalize
     
    CLR要求所有对象都用new操作符创建。
    以下new操作符所做的事情:
    1 计算类型及其所有基类型(一直到System.Object,虽然它没有定义自己的实例字段)中定义的所有实例字段需要的字节数。堆上每个对象都需要一些额外的成员,包括“类型对象指针”和“同步块索引”。CLR利用这些成员管理对象。额外成员的字节数要计入对象大小。
    2 从托管堆中分配类型要求的字节数,从而分配对象的内存,分配的所有字节都设为0。
    3 初始化对象的“类型对象指针”和“同步块索引”成员。
    4 调用类型的实例构造器,传递在new调用中指定的实参。大多数编译器都在构造器中自动生成代码来调用基类构造器。每个类型的构造器都负责初始化该类型定义的实例字段。最终调用System.Object的构造器,该构造器什么都不做,简单地返回。
     
    new执行了所有这些操作之后,返回指向新建对象的一个引用(或指针)。
    并且没有和new操作符对应的delete操作符;换言之,没有办法显式释放为对象分配的内存。CLR采用了垃圾回收机制,自动检测一个对象不再被使用或是访问,并自动释放该对象的内存。
     
    4.2 类型转换
    CLR最重要的特性之一就是类型安全。在运行时,CLR总是知道对象的类型是什么。调用GetType方法即可。
     
    CLR允许将对象转换为它的(实际)类型或者它的任何基类型。
    C#不要求任何特殊语法即可讲对象转换为它的任何基类型,因为向基类型的转换被认为是一种安全的隐式转换;然而,将对象转换为它的某个派生类型时,C#要求开发人员只能进行显式转换,因为这种转换可能在运行时失败。
     
    使用C#的is和as操作符来转型
    is检查对象是否兼容于指定类型,返回Boolean值,is操作符永远不抛出异常;
    CLR的类型检查增强了安全性,但无疑会对性能造成一定影响。这是因为CLR首先必须判断变量引用的对象的实际类型,然后,CLR必须遍历继承层次结构,用每个基类型去核对指定的类型。
    由于这是一个相当常用的编程模式,所以C#专门提供了as操作符,目的是简化这种代码的写法,同时提升性能。CLR核实一个对象是否兼容与一种类型,如果是,as返回同一个对象的非null引用,如果不兼容,as返回null。注意:as操作符只校验一次对象类型。
     
    C#允许类型定义转换操作符方法,详情参见8.5节 “转换操作符方法”。
     
    4.3 命名空间和程序集
    命名空间 对相关的类型进行逻辑分组,开发人员可以通过命名空间方便定位类型。
     
    对于编译器,命名空间的作用就是为类型名称附件以句号分割的符号,使名称变得更长,更可能具有唯一性。
     
    CLR对“命名空间”一无所知。
    C# using指令的另一种形式允许为类型或命名空间创建别名。
     
    命名空间和程序集的关系
    注意,命名空间和程序集(实现类型的文件)不一定相关。特别是,同一个名空间中的类型可能在不同程序集中实现,同一个程序集也可能包含不同命名空间中的类型。
    在文档中查找类型时,文档会明确指出类型所属的命名空间,以及实现了该类型的程序集。
     
    4.4 运行时的相互关系
    本节将解释类型、对象、线程栈和托管堆在运行时的相互关系。
    此外,还将解释调用静态方法、实例方法和虚方法的区别。
     
    “序幕”(prologue)代码:在方法开始做工作前对其进行初始化;
    “尾声”(epilogue)代码:在方法做完工作后对其进行清理,以便返回至调用者。
     
    堆上所有对象都包含两个额外成员:类型对象指针 和 同步块索引。
     
    对象含有一个指针指向对象的类型对象(类型对象中包含静态字段表和方法表)。
     
    CLR创建类型对象时,必须初始化这些成员。CLR开始在一个进程中运行时,会立即为MSCorLib.dll中定义的System.Type类型创建一个特殊的类型对象。Employee和Manager类型对象都是该类型的“实例”。因此,它们的类型对象指针成员会初始化成对System.Type类型对象的引用。当然,System.Type类型对象本身也是对象,内部也有“类型对象指针”成员。这个指针指向它本身,因为System.Type类型对象本身是一个类型对象的“实例”。这就是CLR的整个类型系统及其工作方式。也就是说,GetType方法返回指向对象的类型对象的指针,这样就可以判断系统中的任何对象的真实类型了。
     
     
     
     
  • 相关阅读:
    TOMCAT原理详解及请求过程
    详解Tomcat配置及使用
    Android网络编程(三)Volley使用方法全解析
    Android开发文档翻译之-Services
    竞赛中经常使用的C++写法
    Android消息机制
    boost的内存管理
    二叉树遍历技巧
    【 D3.js 视频系列 】 飞速入门
    [Spring实战系列](19)Servlet不同版本号之间的差别
  • 原文地址:https://www.cnblogs.com/crazytomato/p/7808655.html
Copyright © 2011-2022 走看看