美文网首页
值类型和引用类型的区别

值类型和引用类型的区别

作者: 何蒙其实很好 | 来源:发表于2019-04-23 12:18 被阅读0次

1.值类型(ValueType)

值类型包括:数值类型,结构体,bool型,用户定义的结构体,枚举,可空类型。

值类型的变量直接存储数据,分配在托管栈中。变量会在创建它们的方法返回时自动释放,例如在一个方法中声明Char型的变量name=’C’,当实例化它的方法结束时,name变量在栈上占用的内存就会自动释放

C#的所有值类型均隐式派生自System.ValueType。

结构体:struct(直接派生于System.ValueType)。

数值类型:整型,sbyte(System.SByte的别 名),short(System.Int16),int(System.Int32),long(System.Int64),byte(System.Byte),ushort(System.UInt16),uint(System.UInt32),ulong(System.UInt64),char(System.Char)。

浮点型:float(System.Single),double(System.Double)。

财务计算的高精度decimal型:decimal(System.Decimal)。

bool型:bool(System.Boolean的别名)。

用户定义的结构体(派生于System.ValueType)。

枚举:enum(派生于System.Enum)。

可空类型(派生于System.Nullable<T>泛型结构体,T?实际上是System.Nullable<T>的别名

2.引用类型(ReferenceType)

引用类型包括:数组,用户定义的类、接口、委托,object,字符串,null类型,类。

引用类型的变量持有的是数据的引用,数据存储在数据堆,分配在托管堆中,变量并不会在创建它们的方法结束时释放内存,它们所占用的内存会被CLR中的垃圾回收机制释放。 

数组(派生于System.Array)

用户需定义以下类型:

类:class(派生于System.Object);

接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。接口只是表示一种contract约定[contract])。

委托:delegate(派生于System.Delegate)。

object(System.Object的别名);

字符串:string(System.String的别名)。

3.值类型与引用类型区别:

 值类型引用类型

存储方式直接存储数据本身存储的是数据的引用,数据存储在数据堆中

内存分配分配在栈中的分配在堆中

效率效率高,不需要地址转换效率较低,需要进行地址转换

内存回收使用完后立即回收使用完后不立即回收,而是交给GC处理回收

赋值操作创建一个新对象创建一个引用

类型扩展不易扩展,所有值类型都是密封(seal)的,所以无法派生出新的值类型具有多态的特性方便扩展

实例分配通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中总是在进程堆中分配(动态分配)

值类型和引用类型树形结构:

注:给参数加了fef(out)后,参数是引用传递,这时候传递的是栈地址(指针,引用),否则就是正常的值传递---栈原始数据的拷贝。

 4.内存分配

值类型的实例经常会存储在栈上的。但是也有特殊情况。如果某个类的实例有个值类型的字段,那么实际上该字段会和类实例保存在同一个地方,即堆中。不过引用类型的对象总是存储在堆中。如果一个结构的字段是引用类型,那么只有引用本身是和结构实例存储在一起的(在栈或堆上,视情况而定)。

引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。简称引用类型部署在托管推上。值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。值类型在内存管理方面具有更好的效率,并且不支持多态,适合用做存储数据的载体;引用类型支持多态,适合用于定义 应用程序的行为。 

注:堆栈(stack)是一种后进先出的数据结构。在内存中,变量会被分配在堆栈上来进行操作。堆(heap)是用于为类型实例(对象)分配空间的内存区域,在堆上创建一个对象,会将对象的地址传给堆栈上的变量(反过来叫变量指向此对象,或者变量引用此对象)。

 5.装箱和拆箱

1)装箱就是将一个值类型转换成等值的引用类型

在堆上为新生成的对象(该对象包含数据,对象本身没有名称)分配内存。

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

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

2)拆箱就是将一个引用类型转换成等值的值类型

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

总结

值类型和引用类型理解透彻后,我们知道C#里面是值传递,但是有些变量是引用类型的,在传递和拷贝时需要特别注意。方法传递参数时加上ref(out),为引用传递参数。

值传递仅仅传递的是值,不影响原始值。

引用传递,传递的是内存地址,修改后会改变内存地址对应储存的值。

相关文章

  • 面试

    值类型和引用类型 值类型和引用类型的区别是值类型直接存储其值,而引用类型存储对值的引用。这两种类型存储在内存的不同...

  • 值类型和引用类型的区别

    1.值类型和引用类型的区别(例如:struct 是值类型,class 是引用类型):

  • C#值类型和引用类型

    值类型和引用类型的区别(小结)相同点:引用类型可以实现接口,值类型当中的结构体也可以实现接口;引用类型和值类型都继...

  • JS基本类型、引用类型梳理

    原始值类型与引用值类型 ECMAScript规范中定义了变量的两种类型:原始值类型和引用值类型。区别两种类型的直接...

  • JS数据类型

    数据类型分类和区别 分类 javascript数据类型分为:值类型(基本数据类型)、引用数据类型; 区别 值类型 ...

  • 值类型,引用类型(C#)

    1.值类型与引用类型的区别: CLR支持两只类型:引用类型和值类型。这是.NET语言的基础和关键,他们从类型定义、...

  • Swift 关键词 -- struct/enum/mutatin

    struct struct 值引用 在swift中,类型引用和值引用的区别在于,对于类型引用(class refe...

  • 第4章: 变量、作用域和内存问题

    4.1 基本类型和引用类型的值 区别:基本类型传递的是值, 操作的也是值本身.引用类型传递是对象的引用(也叫地址 ...

  • Java之值类型和引用类型的扩展分析

    大纲: 1.什么是值类型,什么是引用类型? 2.值类型int和引用类型Integer的区别和转换 3.Java之按...

  • 引用类型和值类型区别

    值类型:保存在线程栈上的,由系统自动释放资源 引用类型:保存在托管堆中的,引用类型包括类、接口、委托和装箱值类型r...

网友评论

      本文标题:值类型和引用类型的区别

      本文链接:https://www.haomeiwen.com/subject/jaqvgqtx.html