一、new关键字

CLR要求所有的对象都通过new来创建,代码如下:

Object obj=new Object();

以下是new操作符做的事情

1、计算类型及其所有基类型(一直到System.Object,虽然它没有定义自己的实例字段)中定义的所有实例字段需要的字节数.堆上每个对象都需要一些额外的成员,包括“类型对象指针”和"同步索引块"。CLR利用这些成员管理对象.额外成员的字节数要计入对象的大小.

2、从托管堆中分配类型要求的字节数,从而分配对象的内存,分配的所有字节都设为0

3、初始化对象的"类型对象指针"和"同步索引块"成员

4、调用类型的实例构造器,传递在new调用中指定的实参,大多数编译器都在构造器中自动生成代码来调用基类构造器,每个类型的构造器都负责初始化该类型定义的实例字段.最终调用System.Object的构造器,该构造器什么都不做.

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

二、对象类型转换

1、基础知识

CLR最重要的特性之一就是类型安全.在运行时,CLR总能知道当前对象是什么类型,调用GetType方法即可知道当前对象是什么类型,由于GetTpye是非虚方法,所以一个类型不能伪装成另一个类型.例如Employee类型不能重写GetType方法来返回一个SuperHero类型.

但是,日常开发中,经常需要将一种类型转换成另一种类型,CLR允许将对象转换成其实际类型或者它的任何基类型.每种编程语言都规定了开发人员具体如何进行这种转换.C#不要求任何特殊语法即可将对象转换成它的基类型,因为向基类型转换被认为是一种类型安全的转换.

对象转换成基类型的代码如下:

    public class Program
{
static void Main(string[] args)
{
//因为CLR中,Object是所有类型的基类,所以不需要转型
Object obj = new Person();
}
}
internal class Person { }

然而将一个对象转换成其派生类型(也就是子类型)时,C#要求进行显式的转换,因为这种转换可能会在运行时失败!

将对象转换成其派生类型(子类型),代码如下:

    public class Program
{
static void Main(string[] args)
{
//因为CLR中,Object是所有类型的基类,所以不需要转型
Object obj = new Person(); //需要强制转换,因为Person派生自Object
Person p = (Person)obj;
}
}
internal class Person { }

注:进行强制转换的对象必须是接收类型的派生类型,如果不是,编译器会报System.InvalidCastException异常.

2、使用is和as来进行强制转换

(1)、is操作符

C#中进行类型转换的另一种方式是使用is操作符,is检查对象是否兼容于指定类型,返回boolean值true或者false,注意:is操作符永远不抛出异常,代码如下:

    public class Program
{
static void Main(string[] args)
{
Object obj = new Object();
Console.WriteLine(obj is Person);
Person p = new Person();
Console.WriteLine(p is Person);
Console.ReadKey();
}
}
internal class Person { }

is操作符通常像下面这样使用:

if (stu is Person)
{
Person p = (Person)stu;
}

在上述的代码中,CLR实际进行了两次的代码检查,is操作符首先核实stu是否兼容于Person类型,如果是,在if语句内部转型时,CLR再次核实stu是否引用一个Person类型,CLR的类型检查增强了安全性,但无疑会对性能造成一定的影响,应为CLR首先必须去判断变量引用的实际类型,用每个基类型去核对指定的类型.

2、as操作符

为了简化is操作符的做法,同时提供is操作符的性能,C#专门提供了as操作符,as操作符的工作方式与强制类型转换一样,只是它永远不抛出异常,如果对象不能转换,结果就是null.所以正确使用as操作符的做法是检查转型结果是否为null,如果直接使用这个结果可能会抛出System.NullReferenceException异常,代码如下:

    public class Program
{
static void Main(string[] args)
{
Object obj = new Object();
Person p = obj as Person;//这个转换会失败,但是p会被设为null,不抛出异常
string exceptionInfo = p.ToString();//这里访问p会抛出异常
Console.WriteLine(exceptionInfo);
Console.ReadKey();
}
}
internal class Person { } 

C# new关键字和对象类型转换(双括号、is操作符、as操作符)的更多相关文章

  1. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  2. Java:双括号初始化 /匿名内部类初始化法

    偶然见到一种初始化方式,感到十分新奇: //新建一个列表并赋初值A.B.C ArrayList<String> list = new ArrayList<String>() { ...

  3. 【一通百通】Bash的单双括号建议:多用[[]], 少用[]

    一. bash [  ] 单双括号 基本要素: Ø  [ ] 两个符号左右都要有空格分隔 Ø  内部操作符与操作变量之间要有空格:如  [  “a”  =  “b”  ] Ø  字符串比较中,> ...

  4. Java map双括号初始化方式的问题

    关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代.如下所示: Map map = new HashMap() { { put("Name", "Un ...

  5. 【转载】C#使用is关键字检查对象是否与给定类型兼容

    在C#的编程开发过程中,很多时候涉及到数据类型的转换,如果强行转换数据类型,有时候可能会出现程序运行时错误,C#语言中提供了is关键字可以检查对象是否与给定类型兼容,可先判断类型兼容后再进行对象的转换 ...

  6. Day06_28_Instanceof关键字 和 引用类型转换

    Instanceof关键字 和 引用类型转换 Instanceof 关键字 - instanceof 是 Java 的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean ...

  7. linux shell “(())” 双括号运算符使用

    导读 在刚开始学习inux shell脚本编程时候,对于它的 四则运算以及逻辑运算.估计很多朋友都感觉比较难以接受.特变逻辑运算符"[]"使用时候,必须保证运算符与算数 之间有空格 ...

  8. PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大、小写

    原文:PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大.小写 若要将 CDM 中将 Entity的标识符都设为指定的大小写,则可以这么设定: 打开cdm的情况下,进入T ...

  9. ng1中 如何用双向绑定 实现单向绑定的初始时不显示双括号效果?

    ng1中 如何用双向绑定 实现单向绑定(ng-bind就可以不显示{{}})的初始时不显示双括号效果? AngularJS 实例 页面加载时防止应用闪烁: <div ng-app="& ...

随机推荐

  1. thinkphp做搜索功能

    一般后台都需要做一些搜索功能,直接上图. 至于前端页面大家自己设计.

  2. Float精度丢失

    BigDecimal _0_1 = new BigDecimal(0.1); BigDecimal x = _0_1; for(int i = 1; i <= 10; i ++) { Syste ...

  3. Android破解学习之路(三)——Android游戏 切水果破解

    经过前两篇破解教程,想必大家也是明白了破解的简单流程了. 先对APP进行试用,了解APP运行的大概流程,之后从APP中找出关键字(一般的关键字差不多都是支付失败),之后使用Androidkiller进 ...

  4. 【机器学习】RNN学习

    感谢中国人民大学的胡鹤老师,课程容量巨大,收获颇丰. 之前提到的CNN模型主要用到人类的视觉中枢,但其有一劣势,无论是人类的视觉神经还是听觉神经,所接受到的都是一个连续的序列,使用CNN相当于割裂了前 ...

  5. Android 跨进程启动Activity黑屏(白屏)的三种解决方案

    原文链接:http://www.cnblogs.com/feidu/p/8057012.html 当Android跨进程启动Activity时,过程界面很黑屏(白屏)短暂时间(几百毫秒?).当然从桌面 ...

  6. Unity 5--全局光照技术

    本文整理自Unity全球官方网站,原文:UNITY 5 - LIGHTING AND RENDERING 简介全局光照,简称GI,是一个用来模拟光的互动和反弹等复杂行为的算法,要精确的仿真全局光照非常 ...

  7. FreeCAD源码阅读笔记

    本文目标在于记录在FreeCAD源码阅读中了解到的一些东西. FreeCAD编译 FreeCAD源码的编译最好使用官方提供的LibPack,否则第三方库难以找全,找到之后还需要自己编译,此外还不知道C ...

  8. break and continue

    public class HelloWorld { public static void main(String[] args) { int sum = 0; for (int i = 1; i &l ...

  9. ajax接收json

    l 什么是json? l Json和xml比较 l Ajax如何使用JSON l Ajax接收json响应案例 什么是json? JSON (JavaScript Object Notation) 是 ...

  10. Python 项目实践一(外星人入侵)第一篇

    python断断续续的学了一段实践,基础课程终于看完了,现在跟着做三个小项目,第一个是外星人入侵的小游戏: 一 Pygame pygame 是一组功能强大而有趣的模块,可用于管理图形,动画乃至声音,让 ...