值类型与引用类型
深入解析数据类型
天下程序万变不离其宗,都是由数据结构与算法组成。所谓数据结构,主要讨论的数据本身以及数据之间的关系;而算法,主要围绕着程序的逻辑结构以及各种设计模式、框架等。本次,我大致说一说数据结构中最基本的数据类型。
C#的语法中,数据类型大致分为两种,值类型与引用类型。值类型,包括了简单类型、枚举类型以及结构体类型;引用类型,包括了类类型、接口类型、委托类型、字符串类型以及数组类型,以上总有8种数据类型。
千万不要小看了这几种数据类型,在这8种数据类型中,有着其深刻的内在逻辑关系。
简单类型包括了数值类型、布尔类型以及字节型,工程上也称为模拟量与开关量 。按照数据类型使用范围不同可分三大类,数值类型与布尔类型主要在算术运算与逻辑运算中使用;字节型主要在通信缓存区中使用;而引用类型中的字符串类型主要在显示文本以及存储、读取中使用。三者各司其职,用于不同的地方。
按照数据类型的使用的层次不同可分两大类,枚举类型、结构体类型、类类型以及接口类型属于上层类型;简单类型、委托类型、字符串类型以及数组类型是在上层类型中才使用的下层类型。其中,上层类型使用频率最高的,便是类类型。类类型中,通常包括4个成分,分别是字段、属性、方法以及事件。字段、属性以及方法的参数和返回值,都是简单类型、字符串类型以及数组类型;而事件,则是一种特殊的委托类型。
1.值类型与引用类型的区别
对于数据类型有了更深入的了解之后,我相信你对值类型和引用类型的兴趣也更加浓厚了。
简而言之,值类型与引用类型,在其类型特征上只有两点。其一,数据存储的位置空间(托管堆、线程栈、局部变量栈)不同,值类型存储在线程栈中,而引用类型存储在托管堆中;其二,变量存储的数据内容不同,值类型存储的是数据本身,而引用类型存储的是数据存储的地址。换句话说,也就是值类型与引用类型主要的不同在于,他们的数据内容以及数据存储位置不同。值类型的管理由操作系统负责,而引用类型的管理则由GC(Garbage Collection)负责。
在这里,太过于深入地讨论值类型与引用类型的区别,实质上并没有太大的意义。个人觉得只需要明白值类型与引用类型的以上两大区别即可。
2.参数传递问题剖析
在默认情况下,C#的方法中参数传递都是按值传递进行的。但实际上,参数传递的方式分为4种不同情况:1.值类型参数按值传递;2.引用类型参数按值传递;3.值类型参数按引用传递;4.引用类型参数按引用传递。
参数分为实参和形参两种。值类型参数按值传递,对于值类型按值传递,实质上传递的形参是该实参的一个副本。因此,在方法中,对于形参的改变并不会影响到实参的值。简而言之,在值类型参数按值传递时,实参与形参是两者独立的,互不影响。引用类型按值传递,对于引用类型按值传递,形参也是实参的一个副本,但实参本身存储的是数据存储的地址,即形参与实参均指向数据存储的地址。此时,形参中的值发生了改变,必定会引起实参中的值发生改变,两者犹如指针,共同指向一片地址区。值类型参数按引用传递与引用类型按引用类型传递,方法的定义和调用必须显示地使用ref和out关键字,不可省略。按引用类型传递后,值类型参数传递的形参,实质上是指向实参(存储在线程栈)地址的指针,存储在线程栈上;引用类型参数传递的形参,实质上是指向实参地址(存储在管托堆)的指针,存储在线程栈上。此时,当形参发生改变时,实参中的值也会发生改变。
其实,有过C语言基础的,一看便知C#中引入引用类型的概念实质上就是C语言中的指针类型。在参数的传递和操作中,无非是使用了参数的副本还是参数的地址,一个是假的参数,一个是实质的参数罢了。其中,我想要特殊说明的是,在引用类型按值传递中,有一个特殊情况,就是string类型按值传递的过程中,string类型具有不变性。即一旦一个string类型被赋值,则它就是不可改变的,也就是不能通过代码去修改它的值。此时,想要去修改string类型参数就必须通过引用传递的方式了。