【C#】之 值类型、引用类型及其传参

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/molihuakai_118/article/details/81842479

前言

值类型和引用类型都是相对于变量来说的,是变量存储数据的一种形式。

值类型变量直接存储数据将数据存储在栈中,而引用类型的变量存储的是数据的引用,其真正的数据存储在数据堆中。

栈与堆:
是在编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义。
是程序运行期间动态分配的内存空间,可以根据程序的运行情况确定要分配的堆内存的大小。

一、值类型(ValueType)

1、范围

数值类型:整型、int、long、byte、char、double
结构体:struct、用户定义的结构体
bool型
枚举:enum

2、说明

值类型的变量声明后,无论是否已经赋值,编译器都会为其分配内存空间。
每个变量的内存空间大小可以不同,用来直接存储数据本身(存放到栈上)。
当数据被释放时,期内存空间将会被回收。
每进行一次赋值操作,都会创建一个新对象,为其分配内存存储数据。

例如
声明一个变量a,为其赋值为20,这时在栈上就会分配到一个内存空间,来存储a的值20 。再声明一个变量b,让b=a,这时栈上会在分配出一个内存空间,用来存储b的值。当a的值改变是,不会影响b的值改变。当b的值改变时也不会影响到a的值改变。

二、引用类型(ReferenceType)

1、范围

包括数组、用户定义的类、接口interface、委托delegate、object、字符串string、null类型、类class

2、说明

引用类型的变量持有的是对数据的引用,即申请引用型变量后,内存会为其分配一个很小的空间(空间大小一般相等)用来存储地址(在栈中),而这个地址对应的就是数据在堆中的位置。引用型变量持有的就是这个数据的地址。当新的变量的值在堆中存在时,堆中并不会重新增加一个相同的值,而是在栈中会有一个新的内存来存放这个新变量所持有的引用(即原来数据在堆中的地址)。

变量并不会在创建他们的方法结束时释放内存空间,他们所占用的内存会被CLR中的垃圾回收机制释放。
每进行一个赋值操作都会创建一个新的引用。


申请一个变量a,为其赋值为20 ,在堆中会分配出内存来存储20这个数据,20在堆中的地址会存储在栈中,a持有这个地址。再申请一个变量b,使b=a,栈中会将a持有的这个地址同时赋值给b,a和b同时拥有堆中20这个数据的地址。当改变b=10,堆中的这个20的数据会变为10,而此时a与b用的是同一个地址,所以此时a的值也会变为10.

三、值类型与引用类型的区别

角度 值类型 引用类型
存储方式 直接存储数据本身 存储的是数据的引用,数据存储在堆中
内存分配 分配在栈中 分配在堆中
效率 高,不需要地址转换 低,需要地址转换
内存回收 使用完后立即回收 使用完后不立即回收,而是给GC处理
赋值操作 创建一个新对象 创建一个引用
类型扩展 不易扩展,所有类型都是封闭的,无法派生出新的类型 具有多态性,方便扩展
实例分配 在线程栈上分配,静态分配(有时可以动态) 在进程堆中分配,动态分配

总结:
值传递仅仅传递的是值,不影响原始值。
引用传递,传递的是内存地址,修改后会改变内存地址对应储存的值。

四、装箱和拆箱

1、装箱

将值类型转变成引用类型
在堆上为新生成的对象(该对象包含数据,对象本身没有名称)分配内存。

将堆栈上值类型变量的值拷贝到堆上的对象中。

将堆上创建的对象的地址返回给引用类型变量(从程序员角度看,这个变量的名称就好像堆上对象的名称一样)。

2、拆箱

将引用型变量变成值类型
将引用类型变量堆上的值拷贝到栈上面。

3、比较

名称 | 值类型 | 引用类型
表示类型 | 基本类型 | 类,数组,接口 ,C#特有的委托.
存储内容 | 值 | 值的引用
存储位置 | 堆栈 | 托管堆

五、传参

在C#中很多变量都是按值传递的,但是也有个别的变量是引用类型的,方法传递参数时加上ref(out),为引用传递参数,使用时都会改变原来参数的数值。

ref可以把参数的数值传递进函数,需要在外面进行初始化,但是out是要把参数清空,就是说无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以必须在函数内部初始化一次。

说明:
1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。

2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

好多博客上说ref是有进有出,out是只进不出,想一想好像真的是这样。

猜你喜欢

转载自blog.csdn.net/molihuakai_118/article/details/81842479