跟小静读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 ,如需转载请自行联系原作者
相关文章
|
4月前
|
Java C#
C# 面向对象编程解析:优势、类和对象、类成员详解
OOP代表面向对象编程。 过程式编程涉及编写执行数据操作的过程或方法,而面向对象编程涉及创建包含数据和方法的对象。 面向对象编程相对于过程式编程具有几个优势: OOP执行速度更快,更容易执行 OOP为程序提供了清晰的结构 OOP有助于保持C#代码DRY("不要重复自己"),并使代码更易于维护、修改和调试 OOP使得能够创建完全可重用的应用程序,编写更少的代码并减少开发时间 提示:"不要重复自己"(DRY)原则是有关减少代码重复的原则。应该提取出应用程序中常见的代码,并将其放置在单一位置并重复使用,而不是重复编写。
68 0
|
25天前
|
开发框架 安全 .NET
|
12天前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
14 2
|
4月前
|
C#
C#的类和对象的概念学习案例刨析
【5月更文挑战第17天】C#是一种面向对象的语言,以类和对象为核心。类作为对象的模板,定义了属性(如Name, Age)和行为(如Greet)。对象是类的实例,可设置属性值。封装通过访问修饰符隐藏实现细节,如Customer类的私有name字段通过Name属性访问。继承允许新类(如Employee)从现有类(Person)继承并扩展。多态让不同对象(如Circle, Square)共享相同接口(Shape),实现抽象方法Area,提供灵活的代码设计。
61 1
|
4月前
|
C#
C#对象初始化器
C#对象初始化器
|
4月前
|
存储 C#
C#对象和类
C#对象和类
34 0
|
4月前
|
存储 C#
C#基础语法(类和对象)
C#基础语法(类和对象)
32 2
|
4月前
|
存储 C#
C# 数据类型与类型转换:包含教程与示例
使用正确的数据类型对应于相应的变量是重要的;这样可以避免错误、节省时间和内存,还会使您的代码更易于维护和阅读。最常见的数据类型有:
47 0
|
4月前
|
XML 存储 JSON
C# | 使用Json序列化对象时忽略只读的属性
将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。 在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。 本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。
129 0
C# | 使用Json序列化对象时忽略只读的属性