C#值类型和引用类型的区别

如题所述

(1)值类型:数据存储在内存的堆栈中,从堆栈中可以快速地访问这些数据,因此,值类型表示实际的数据。
(2)引用类型:对象、数组、函数。

1、值类型:包括:sbyte、short、int、long、float、double、decimal(以上值类型有符号)byte、ushort、uint、ulong(以上值类型无符号)bool、char
2、引用类型:包括:对象类型、动态类型、字符串类型。二、具体区别:
1、值类型:byteb1=1;byteb2=b1;Console.WriteLine("{0},{1}。",b1,b2);b2=
2;Console.WriteLine("{0},{1}。",b1,b2);Console.ReadKey();解释:byteb1=1;声明b1时,在栈内开辟一个内存空间保存b1的值1。byteb2=b1;声明b2时,在栈内开辟一个内存空间保存b1赋给b2的值1。Console.WriteLine("{0},{1}。",b1,b2);输出结果为1,1。b2=2;将b2在栈中保存的值1改为
2。Console.WriteLine("{0},{1}。",b1,b2);输出结果为1,2。
2、引用类型:复制代码。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-11-22

1、分配不同。

值类型分配在线程堆栈上(管理由操作系统负责),引用类型分配在托管堆上(管理由垃圾回收器GC负责)。

管理指内存空间的分配和释放:

变量本身是存储在堆栈上的(无论是值类型变量还是引用类型变量);

但是对于实际数据:引用类型存在托管堆上,值类型存在堆栈。

2、继承不同。

值类型继承自valueType,valueType继承自System.Object;引用类型直接继承自System.Object。

3、释放方式不同。

值类型在作用域内结束时,会被操作系统自释放,减少托管堆压力;引用类型则靠GC。因此值类型在性能上由优势。

4、属性不同。

值类型是密封的,不能作为基类。引用类型一般具有继承性.

5、null上的不同。

值类型不能为null,默认初始化为该类型的默认值;引用类型默认初始化为null。

6、参数传递上的不同。

值类型作为参数传递时,不影响本身。引用类型作为参数传递时,会改变最终该变量的值。

本回答被网友采纳
第2个回答  2018-03-23

如果你学过C/C++的话,这点很容易理解,C#中的一个重要特征就是所有一切资源都可以抽象为类,并可实例化对象,包括基本数据类型,所有一切类的基类是Object,因此C#是完全面向对象的语言。

在C/C++中,“int,byte,long,bool,char ..."这些类型虽然不是真正意义上的类,但是从某种角度看,其实也具有类的某些特征,比如你可以把int看做编译器内置的一个类,当你int a进行定义变量时,等于用int类创建了一个称作a的对象,只是C#告诉你,int就是个类,它有自己的方法和属性,比如ToString(),而且所有的类型都继承于Object类,而C/C++中没有这么彻底。

C/C++中,你可以直接用基本变量类型创建一个变量,变量名指代一个系统分配的地址,当使用变量名操作时可以直接操作数据,因此这种类型可以叫做值类型,只不过由于C/C++中根本没把基本类型表示为类所以也没有值类型这种表述,直接定义变量时,变量被分配在栈上,叫做静态分配。而当我们在定义一个指针变量时,比如100个元素的动态数组: int *p=new int[100],或者动态分配一个变量并初始化: int *p=new int(10),都是在程序运行时分配到堆上面的,并且把地址赋值给指针p。

说这些C/C++的概念是想告诉你,C#中的值类型和引用类型就是和C/C++静态分配和动态分配是一样的。C#中的值类型,它可以定义后直接使用(不需要new,没有指针),分配在栈上;引用类型其实就是将指针和所指内存块以及其他额外数据封装了,因为在C#中全面对象化,对用户不可见。但是本质还是一样的,因此值类型( int a=10 ) 就是直接进行分配内存后存储,而引用类型必须进行装箱:object o=10,装箱的过程就是在堆上分配一个内存块,存放a的值以及其他额外数据并返回地址,也就是对象的引用赋值给o,而你是不可以直接将o按指针来操作的(所以称为引用)。由于基本类型是内置的,所以这类对象的创建不需要显式去new,当然你一定要自己new也不会错 object o=new int(),因为C#是完全面向对象的,一切的实体都可以new,创建格式标准化的(除了接口,因为它没有实体)。

最后说说值类型,由于C#一切都是面向对象的,因此就算是值类型也是个类,因此基本类型升级后C/C++中很简单变量升级为结构,以满足面向对象统一接口,因为C/C++中类的本质就是结构的升级版(增加了函数),而C#中的值类型的存在为了效率,所以采用静态结构体。虽然这两种语言是完全不同的语言,但是血缘上还是有关系的,有些地方可以互通和借鉴,这个可以帮助我们方便的理解和学习。

下图为VS2010 C#中 右键查int类型的定义,注意是struct,值类型,结构的特点就是静态和效率,所以C#中基本类型都是结构:

下图为VS2010 C#中 右键查object类型的定义,注意是class,其特点就是动态和灵活,所以C#中引用类型都是类:

本回答被网友采纳
第3个回答  2018-03-23
1. 值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的

地址。
2. 值类型存取速度快,引用类型存取速度慢。
3. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
4. 值类型继承自System.ValueType,引用类型继承自System.Object
5. 栈的内存分配是自动释放;而堆在.NET中会有GC来释放
6. 值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。

7. 值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中,而实际
数据则保存在堆中。注意,堆和堆栈是两个不同的概念,在内存中的存储位置也不相同,堆一般用于存储
可变长度的数据,如字符串类型;而堆栈则用于存储固定长度的数据,如整型类型的数据int(每个int变量
占用四个字节)。由数据存储的位置可以得知,当把一个值变量赋给另一个值变量时,会在堆栈中保存两
个完全相同的值;而把一个引用变量赋给另一个引用变量,则会在堆栈中保存对同一个堆位置的两个引用
,即在堆栈中保存的是同一个堆的地址。在进行数据操作时,对于值类型,由于每个变量都有自己的值,
因此对一个变量的操作不会影响到其它变量;对于引用类型的变量,对一个变量的数据进行操作就是对这
个变量在堆中的数据进行操作,如果两个引用类型的变量引用同一个对象,实际含义就是它们在堆栈中保
存的堆的地址相同,因此对一个变量的操作就会影响到引用同一个对象的另一个变量。本回答被网友采纳
第4个回答  2021-07-01

值类型、引用类型区别:

    值类型内容存储在(栈)上。引用类型指针存储在(栈)上,内容存储在(堆)上。

    值类型和引用类型最大的不同是:传递的效率和影响:效率指:软件运行时,复杂功能在大量运算,毫秒级上内存一直在复制和分配,一组数据的值拷贝和指针拷贝,cpu性能和内存表现差异大,影响指:修改方法里的数据会不会影响到方法外的数据对象。

    值类型=其他变量时是复制内容(替换栈内容),引用类型=其他变量时是替换指针(替换栈指针)。

    值类型赋值时(例=1)是替换内容(替换栈内容),引用类型=new时是新分配内存(新分配堆内存)和替换指针(替换栈指针)。

    值类型在方法传递参数过程中是复制1份内容(新分配栈内容),引用类型在方法传递过程中是复制1个指针(新分配栈指针),指向同1个内容,内容没复制。

    值类型在方法里修改不影响方法外变量,引用类型在方法里修改,因为指向同1个内容,方法外的值也同步变化。

字符串是特殊的引用类型:

    字符串是特殊的引用类型,每次=新字符串实际都改变一次栈指针(新分配堆内存,替换栈指针),而没有改变值。

    字符串传给方法是1个指针(新分配栈指针)。方法内=新字符串是替换方法内的指针(替换新栈指针),不影响方法外的指针(不影响原栈指针),所以表现看过去与值传递一致。

结构体struct值类型、class引用类型区别:

 结构体struct是值类型,但是结构体中的字符串、数组、类存放的是指针,和值一起存在栈上。

   所谓值类型, 结构体的表现就是传给方法是复制1套指针和1套值,在方法内修改结构体1级属性(修改结构体字符串、new数组、new类)改的是方法内结构体的指针(1级指针),无法改变方法外结构体的指针,所以不影响方法外的结构体,但是修改数组内数据和类属性会影响方法外的结构体(因为改的是1级指针指向的内容)。

    class是引用类型,传给方法是1个指针。方法内替换属性会影响方法外的对象(因为修改的是指针指向的内容)。但是方法内再次=new对象是替换方法内的对象指针,不影响方法外的对象,再替换属性就不影响方法外的对象。

相似回答