跟小静读CLR via C#(03)- 对象创建和类型转换

简介:

跟小静读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;

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

你答对了吗?微笑




    本文转自 陈敬(Cathy) 博客园博客,原文链接:http://www.cnblogs.com/janes/archive/2011/07/05/2098065.html ,如需转载请自行联系原作者
相关文章
|
3月前
|
Java C#
C# 面向对象编程解析:优势、类和对象、类成员详解
OOP代表面向对象编程。 过程式编程涉及编写执行数据操作的过程或方法,而面向对象编程涉及创建包含数据和方法的对象。 面向对象编程相对于过程式编程具有几个优势: OOP执行速度更快,更容易执行 OOP为程序提供了清晰的结构 OOP有助于保持C#代码DRY("不要重复自己"),并使代码更易于维护、修改和调试 OOP使得能够创建完全可重用的应用程序,编写更少的代码并减少开发时间 提示:"不要重复自己"(DRY)原则是有关减少代码重复的原则。应该提取出应用程序中常见的代码,并将其放置在单一位置并重复使用,而不是重复编写。
51 0
|
1月前
|
存储 C#
C#对象和类
C#对象和类
15 0
|
3月前
|
存储 C#
C#基础语法(类和对象)
C#基础语法(类和对象)
20 2
|
4月前
|
Java 编译器 C#
【从Java转C#】第三章:对象和类型
【从Java转C#】第三章:对象和类型
|
9月前
|
C#
C#——类和对象
C#——类和对象
53 0
|
4月前
|
XML 存储 JSON
C# | 使用Json序列化对象时忽略只读的属性
将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。 在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。 本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。
53 0
C# | 使用Json序列化对象时忽略只读的属性
|
9月前
|
开发框架 .NET 编译器
C# Lambda表达式和linq表达式 之 匿名对象查询接收
C# Lambda表达式和linq表达式 之 匿名对象查询接收
|
前端开发 程序员 C#
【C#】通过扩展对象的方式,对字符串等数据类型进行数据进一步处理
在本篇文章中,我们讲一起了解下对象扩展的使用 在实际项目开发中,对象扩展使用的场景还是挺多的,比如:需要对时间值进行再处理,或者字符串中的斜杠(/)转为反斜杠(\)
90 0
|
安全 Java 程序员
C#编程学习17:类与对象学习小结
C#编程学习17:类与对象学习小结
C#编程学习17:类与对象学习小结
|
JSON C# 数据格式
C# 字符串对象转JSON
C# 字符串对象转JSON
181 4