C# new关键字和对象类型转换(双括号、is操作符、as操作符)
一、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操作符)的更多相关文章
- Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询
Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...
- Java:双括号初始化 /匿名内部类初始化法
偶然见到一种初始化方式,感到十分新奇: //新建一个列表并赋初值A.B.C ArrayList<String> list = new ArrayList<String>() { ...
- 【一通百通】Bash的单双括号建议:多用[[]], 少用[]
一. bash [ ] 单双括号 基本要素: Ø [ ] 两个符号左右都要有空格分隔 Ø 内部操作符与操作变量之间要有空格:如 [ “a” = “b” ] Ø 字符串比较中,> ...
- Java map双括号初始化方式的问题
关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代.如下所示: Map map = new HashMap() { { put("Name", "Un ...
- 【转载】C#使用is关键字检查对象是否与给定类型兼容
在C#的编程开发过程中,很多时候涉及到数据类型的转换,如果强行转换数据类型,有时候可能会出现程序运行时错误,C#语言中提供了is关键字可以检查对象是否与给定类型兼容,可先判断类型兼容后再进行对象的转换 ...
- Day06_28_Instanceof关键字 和 引用类型转换
Instanceof关键字 和 引用类型转换 Instanceof 关键字 - instanceof 是 Java 的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean ...
- linux shell “(())” 双括号运算符使用
导读 在刚开始学习inux shell脚本编程时候,对于它的 四则运算以及逻辑运算.估计很多朋友都感觉比较难以接受.特变逻辑运算符"[]"使用时候,必须保证运算符与算数 之间有空格 ...
- PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大、小写
原文:PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大.小写 若要将 CDM 中将 Entity的标识符都设为指定的大小写,则可以这么设定: 打开cdm的情况下,进入T ...
- ng1中 如何用双向绑定 实现单向绑定的初始时不显示双括号效果?
ng1中 如何用双向绑定 实现单向绑定(ng-bind就可以不显示{{}})的初始时不显示双括号效果? AngularJS 实例 页面加载时防止应用闪烁: <div ng-app="& ...
随机推荐
- ios2048小游戏
最近突然想写一个2048的小游戏,由于全部是自定义控件,所以程序看起来冗杂,但是核心的算法部分还是很不错的,大家感兴趣的可以仔细看看. 声明部分: #import <UIKit/UIKit.h& ...
- TreeSet(一)--排序
TreeSet(一) 一.TreeSet定义: 与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的. 1)TreeSet类概述 ...
- 【epubcfi函数generateRangeFromCfi和generateCfiFromRange】两者的区别和适用性,以及另一种实现
epubcfi是描述epub规范电子书中文本位置的一种描述符,它是形如" epubcfi(/6/4[Section0017.xhtml]!4/42/178/1:0,4/42/198/1:1) ...
- 伸缩的菜单,用toggle()重写
<!DOCTYPE ><html><head><meta charset="UTF-8"/><title>伸缩的菜单,用 ...
- 初识java这个小姑娘(二)
妙解垃圾回收机制 周一,早高峰. 一段考验一个人耐力.智力.开车技术以及脾气的路. 我把车开进了一个没有红绿灯的丁字路口,然后就没有然后了. 来自三个方向的大车小车开始在不大的一块空间里开始互相斗智斗 ...
- C# (using Newtonsoft.Json) Json 转换用法小总结
//序列化 string Json字符串 = JsonConvert.SerializeObject(目标对象); // 字符串转化为对象 string UserJson = "{\&quo ...
- Zookeeper 集群安装
负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据[均匀]分摊到多个操作单元上执行,负载均衡的关键在于[均匀].常见互联网分布式架构如上,分为客户端 ...
- python 爬取国家粮食局东北地区玉米收购价格监测信息
#!/usr/bin/python# -*- coding: UTF-8 -*-import reimport sysimport timeimport urllibimport urllib.req ...
- Loadrunner 中socket协议RecvBuffer接收到数据长度为空
socket通讯,有两种方式,一种是建立长连接(TCP),建立后,不停的发送,接收.另外一种是建立短连接(UDP),建立连接,发送报文,接收响应,关闭连接.两种方式 server的开销不同. 今天出现 ...
- Jenkins+tomcat+jdk setup
Jenkins download: http://jenkins-ci.org/ jdk version:jdk-7u45-linux-x64.tar.gz tomcat version:apache ...