一、 创建对象

CLR要求用new操作符创建对象,这个操作符在编译时产生的IL指令为newobj。例如:

Student XiaoJing=new Student(“XiaoJing”,”1986”);

那么在创建过程中,究竟发生了什么事呢?

  • 分配空间。在托管堆中分配该类所需要字节数的内存空间。
  • 初始化对象的附加成员。每个对象有两个附加成员:一是指向类方法表的指针;二是SyncBlockIndex成员,CLR用该字段进行线程同步控制,某些位还可以用作垃圾回收标 记等等。CLR通过这两个成员管理对象实例。
  • 调用构造函数。其间可以传入指定的参数。
二、 类型转换

C#中,向基类转换直接隐式进行就可以;向派生类转换则需要显示进行,因为有可能会失败。在运行时,CLR会检查转型操作以确保是将对象转化为它的实际类型或者它的基类型。

class Animal { }

class Dog : Animal { }

Animal a=new Dog();

Dog b=(Dog)a;           //显示转换,基类向派生类

Animal a=new Dog(); //隐式转换,派生类向基类

IS和AS?

要想检查对象和类是否兼容,有两种方式:Is和As。

  • Is关键字在使用中经常需要转换两次。首先判断类型兼容,然后常伴随着一次显示转换。

If(a is Dog)//第一次转换

{

Dog g=a;//第二次转换

………

}

  • As关键字转换一次,然后判断转换后的变量是否为null就可以了。所以该方式性能相对高一些。

Dog g=a as Dog;//转换一次,失败则为null

If(g!=null) {…}

三、 实例考察

下面来看一个类型转换的例子,看每行代码在编译和运行时是否能够正确通过?如果你都答对了,那么本节课的理解就及格了。

还是上面的两个类,Animal和Dog,主要考察类型转换的知识。

代码

正确

编译错误

运行错误

class Program

     

{

     

static void Main(string[] args)

     

{

     

Object o1 = new Object();

   

Object o2 = new Animal();

   

Object o3 = new Dog();

   

Object o4 = o3;

   

Animal Animal1 = new Animal();

   

Animal Animal2 = new Dog();

   

Dog Dog1 = new Dog();

   

Animal Animal3 = new Object();

 

√①

 

Dog Dog2 = new Object();

 

√②

 

Animal Animal4 = Dog1;

   

Dog Dog3 = Animal2;

 

√③

 

Dog Dog4 = (Dog)Dog1;

   

Dog Dog5 = (Dog)Animal2;

   

Dog Dog6 = (Dog)Animal1;

   

√④

Animal Animal5 = (Animal)o1;

   

√⑤

Animal Animal6 = (Dog)Animal2;

   

}

     

}

     

错误点解析:

① Animal Animal3 = new Object();

基类向派生类转换应该显示进行,所以编译就报错了。实际上就算改成显示转型也会发生运行时错误,因为对象类型不兼容。可以尝试改成Animal Animal3 = (Animal)o2;

② Dog Dog2 = new Object();

理由同①,正解为Dog Dog2 =(Dog)o3;

③ Dog Dog3 = Animal2;

理由同①,正解为Dog Dog3 =(Dog) Animal2;

④ Dog Dog6 = (Dog)Animal1

基类向派生类显示转型,语法上没有错误因此编译通过。但在运行时,CLR会检查转型操作以确保是将对象转化为它的实际类型或者它的基类型。而Animal1对象是Animal类型而非Dog类型,因此转型时发生失败。如果添加一句Animal1=new Dog();再执行该转型则会成功。

⑤ Animal Animal5 = (Animal)o1;

理由同④。这里不再赘述了。

CLR via C#(03)- 对象创建和类型转换的更多相关文章

  1. JVM的艺术-对象创建与内存分配机制深度剖析

    JVM的艺术-对象创建与内存分配机制深度剖析 引言 本章将介绍jvm的对象创建与内存分配.彻底带你了解jvm的创建过程以及内存分配的原理和区域,以及包含的内容. 对象的创建 类加载的过程 固定的类加载 ...

  2. (1)访问控制 (2)final关键字 (3)对象创建的过程 (4)多态

    1.访问控制(笔试题)1.1 常用的访问控制符 public - 公有的 protected - 保护的 啥也不写 - 默认的 private - 私有的 1.2 访问控制符的比较 访问控制符 访问权 ...

  3. [你必须知道的.NET]第十九回:对象创建始末(下)

    本文将介绍以下内容: 对象的创建过程 内存分配分析 内存布局研究 接上回[第十八回:对象创建始末(上)],继续对对象创建话题的讨论>>> 2.2 托管堆的内存分配机制 引用类型的实例 ...

  4. [你必须知道的.NET]第十八回:对象创建始末(上)

    本文将介绍以下内容: 对象的创建过程 内存分配分析 内存布局研究 1. 引言 了解.NET的内存管理机制,首先应该从内存分配开始,也就是对象的创建环节.对象的创建,是个复杂的过程,主要包括内存分配和初 ...

  5. Java中对象创建过程

    本文介绍的对象创建过程仅限于普通Java对象,不包括数组和Class对象. 1.类加载检查 虚拟机遇到一条new指令时,首先去检查该指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用 ...

  6. Progress.js – 为页面上的任意对象创建进度条效果

    Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...

  7. 《JavaScript模式》第5章 对象创建模式

    @by Ruth92(转载请注明出处) 第5章:对象创建模式 JavaScript 是一种简洁明了的语言,并没有其他语言中经常使用的一些特殊语法特征,如 命名空间.模块.包.私有属性 以及 静态成员 ...

  8. C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例

    Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...

  9. Spring对象绑定与类型转换

    Spring对象绑定与类型转换 Spring的框架体系中,到处充斥着对象绑定从bean的初始化autowired属性,SpringMvc 中对对象的绑定等.Spring对象绑定和类型转换在Spring ...

随机推荐

  1. 访问者(Visitor)模式

    http://www.cnblogs.com/zhenyulu/articles/79719.html 一. 访问者(Visitor)模式 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作. ...

  2. Markdown入门教程

    Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的语法十分简单.常用的标记符号也不 ...

  3. git 教程(6)--管理修改

    现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ...

  4. 二、 显示加载数据过程的JS

  5. Android菜单Menu的创建

    在res目录下的menu文件夹下创建一个main.xml文件,内容如下: <?xml version="1.0" encoding="utf-8"?> ...

  6. Java读写文件通用格式

    String path = "I:\\"; File file = new File(path + "user_id_pair.txt"); FileReade ...

  7. SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

    在用php返回json数据的时候如果出现这种错误,先检查一下php中是否有使用var_dump()函数 这个函数会在页面输出测试变量的结构,浏览器会将这个当做json数据,所以就报错了....

  8. SQL Server常用命令

    1.DECLARE DECLARE命令用于声明一个或多个局部变量.游标变量或表变量. 注:如果定义的变量是字符型,应该指定data_type表达式中其最大长度,否则系统认为其长度为1. declare ...

  9. Linux下安装gcc和g++

    以CentOS为例,安装后是没有C语言和C++编译环境的,需要手动安装,最简单的是用yum的方式安装,过程如下: 1.安装gcc yum install gcc 询问是否,按y键回车即可,或者 yum ...

  10. 5.js模式-职责链模式

    1. 职责链模式 将对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. var chain = function(fn){ this.fn = fn; this.successor = ...