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

时间:2022-09-23 23:25:18

一、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 { }

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

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操作符)

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

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

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

  2. 【一通百通】Bash的单双括号建议:多用&lbrack;&lbrack;&rsqb;&rsqb;&comma; 少用&lbrack;&rsqb;

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

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

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

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

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

  5. Day06&lowbar;28&lowbar;Instanceof关键字 和 引用类型转换

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

  6. linux shell &OpenCurlyDoubleQuote;&lpar;&lpar;&rpar;&rpar;” 双括号运算符使用

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

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

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

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

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

  9. java对象类型转换和多态性

    html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...

随机推荐

  1. 巧用margin&sol;padding的百分比值实现高度自适应(多用于占位,避免闪烁)

    本文依赖于一个基础却又容易混淆的css知识点:当margin/padding取形式为百分比的值时,无论是left/right,还是top/bottom,都是以父元素的width为参照物的!也许你会说, ...

  2. Hibernate的Annotation注解

    当项目变得比较大的时候,如何还使用hbm.xml文件来配置Hibernate实体就会变得比较复杂.这里Hibernate提供了Annotation注解方式,使得Hibernate的映射文件变得很方便管 ...

  3. Scorm 1&period;2 开发文档

    原文出处 电华教育研究杂志2010年第7期<SCORM标准学习跟踪机制的研究与实现> http://blog.sina.com.cn/s/blog_964ec55001014nl0.htm ...

  4. str&lowbar;翻转字符串

    1. 给一个句子,翻转每个单词,单词内部不翻转 $str = "dog loves pig"; $ret = turnSentence($str); var_dump($ret); ...

  5. salesforce 零基础学习(六十六)VF页面应善于使用变量和函数(二)常用函数的使用

    上一篇介绍VF中常用的变量,此篇主要内容为VF页面可以直接使用的函数,主要包括Date相关函数,Text相关函数,Information相关函数以及logic相关函数,其他相关函数,比如math相关函 ...

  6. FFmpeg AVCodec

    FFmpeg编解码 FFmpeg支持绝大多数视频编解码格式,如何遍历FFmpeg编解码器? 编解码器以链表形式存储,使用av_codec_next() 函数可以获取编解码器指针,当参数为NULL时,获 ...

  7. w9 Ansible批量管理与维护

    Ansible是2013年推出的一种通用自动化工具,可用于配置管理或工作流程自动化.配置管理是一种“基础架构代码”实践,它将事物编码,例如应该在系统上安装什么包和版本,或者应该运行什么守护进程.工作流 ...

  8. MySql之插入操作

    一:插入一行数据 INSERT INTO tableName(列名...) VALUES(对应列名的值); 二:插入多行 INSERT INTO tableName(列名...) VALUES(对应列 ...

  9. (二)收集的MongoDB命令集合

    一:针对整个数据库的 1."show dbs" 命令可以显示所有数据的列表. 2. "db" 命令可以显示当前数据库对象或集合. 3."use&quo ...

  10. PAT甲题题解-1050&period; String Subtraction &lpar;20&rpar;-水题

    #include <iostream> #include <cstdio> #include <string.h> #include <algorithm&g ...