CLR via C#(03)- 对象创建和类型转换
一、 创建对象
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)- 对象创建和类型转换的更多相关文章
- JVM的艺术-对象创建与内存分配机制深度剖析
JVM的艺术-对象创建与内存分配机制深度剖析 引言 本章将介绍jvm的对象创建与内存分配.彻底带你了解jvm的创建过程以及内存分配的原理和区域,以及包含的内容. 对象的创建 类加载的过程 固定的类加载 ...
- (1)访问控制 (2)final关键字 (3)对象创建的过程 (4)多态
1.访问控制(笔试题)1.1 常用的访问控制符 public - 公有的 protected - 保护的 啥也不写 - 默认的 private - 私有的 1.2 访问控制符的比较 访问控制符 访问权 ...
- [你必须知道的.NET]第十九回:对象创建始末(下)
本文将介绍以下内容: 对象的创建过程 内存分配分析 内存布局研究 接上回[第十八回:对象创建始末(上)],继续对对象创建话题的讨论>>> 2.2 托管堆的内存分配机制 引用类型的实例 ...
- [你必须知道的.NET]第十八回:对象创建始末(上)
本文将介绍以下内容: 对象的创建过程 内存分配分析 内存布局研究 1. 引言 了解.NET的内存管理机制,首先应该从内存分配开始,也就是对象的创建环节.对象的创建,是个复杂的过程,主要包括内存分配和初 ...
- Java中对象创建过程
本文介绍的对象创建过程仅限于普通Java对象,不包括数组和Class对象. 1.类加载检查 虚拟机遇到一条new指令时,首先去检查该指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用 ...
- Progress.js – 为页面上的任意对象创建进度条效果
Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...
- 《JavaScript模式》第5章 对象创建模式
@by Ruth92(转载请注明出处) 第5章:对象创建模式 JavaScript 是一种简洁明了的语言,并没有其他语言中经常使用的一些特殊语法特征,如 命名空间.模块.包.私有属性 以及 静态成员 ...
- C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例
Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...
- Spring对象绑定与类型转换
Spring对象绑定与类型转换 Spring的框架体系中,到处充斥着对象绑定从bean的初始化autowired属性,SpringMvc 中对对象的绑定等.Spring对象绑定和类型转换在Spring ...
随机推荐
- unity销毁层级物体及 NGUI 深度理解总结
http://www.2cto.com/kf/201311/258811.html 1.想找到层级面板中某个物体,并销毁,利用下面的代码: GameObject obj = GameObjec ...
- caffe_windows安装
CUDA:链接:http://pan.baidu.com/s/1nvyA3Qp 密码:h0f3 cudnn:链接:http://pan.baidu.com/s/1hr3Ug76 密码:vmdq caf ...
- C++虚函数、虚继承、对象内存模型(转)
参考:http://blog.csdn.net/hxz_qlh/article/details/14633361 需要注意的是虚继承.多重继承时类的大小.
- Android自定义标题栏
预览一下效果: 素材: 新建一个布局title_bar.xml,代码如下: <?xml version="1.0" encoding="utf-8"?&g ...
- JVM(java 虚拟机)内存设置
一.设置JVM内存设置 1. 设置JVM内存的参数有四个: -Xmx Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定: -Xms Ja ...
- rest api设计的一般原则
本文参考自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html,http://www.dongming8.cn/?p=590 服务器端: 1 ...
- 比较NHibernate和Entity Framework
葡萄牙的一位开发者 Ricardo Peres 最近发布了一篇文章,以看起来无偏见的形式对领先的两种 .NET ORM:NHibernate 和 Entity Framework 进行了比较. 我们建 ...
- Smallest Rectangle Enclosing Black Pixels
An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...
- Java从网络读取图片并保存至本地
package cn.test.net; import java.io.File; import java.io.FileOutputStream; import java.io.InputStrea ...
- CMake入门以及学习笔记
使用cef3替代chromium内核开发产品过程中,第一次接触到系统构建,使用了最常见的CMake.CMake虽然在构建系统中用的比较多,但是使用到的程序员还是很少的.现在在国内能找到的相关资料和博客 ...