- A+
本章将和大家分享.NET中值类型与引用类型以及值传递与引用传递。
一、值类型与引用类型
值类型:数值类型、结构体、bool类型、枚举、可空类型(例如:int、double、bool、char、decimal、struct、enum)等等。
引用类型:数组、委托、接口、object、集合、字符串、用户自定义的类等等。
存储:
值类型的值是存储在内存的栈当中。
引用类型的值是存储在内存的堆当中。(引用类型同时也会在栈中开辟一块空间,用于存放这个值在堆中的地址。)
示例图如下所示:
二、装箱与拆箱
装箱:就是将值类型转换为引用类型。
拆箱:就是将引用类型转换为值类型。
看两种类型是否发生了装箱或者拆箱,前提是要看这两种类型是否存在继承关系。没有继承关系的一定不会发生拆箱或者装箱,有继承关系的才有可能发生拆箱或者装箱。
示例:
using System; namespace ValueTypeAndReferenceType { class Program { static void Main(string[] args) { { int n = 9; object o = n; //装箱 int m = (int)o; //拆箱 } //string和int没有继承关系,故没有发生拆箱或装箱 { string str = "123"; int n = Convert.ToInt32(str); } //int继承IComparable,故此处是装箱 { int n = 10; IComparable i = n; //装箱 } } } }
拆箱和装箱会影响程序的性能,故在程序开发过程中应尽量避免发生装箱或者拆箱。
三、值传递与引用传递
值类型在复制的时候,传递的是这个值的本身。
引用类型在复制的时候,传递的是对这个对象的引用。
示例图如下所示:
从即时窗口中可以很直观的看出值传递和引用传递的区别。(此处用到了&)
字符串的不可变性:
从上图中可以很直观的看出字符串的不可变性,改变其中一个值另外一个不受影响。因为改变的时候如果内存中不存在这个新的字符串值它就会去重新开辟一块内存空间存储。
1、值类型按值传递
可以发现值类型按值传递时两个变量在栈中的地址是不同的,故两个变量的值互不影响。
运行结果如下所示:
2、值类型按引用传递
可以发现值类型按引用传递的时候两个变量的栈地址是一样的,故改变其中一个变量的值另外一个变量会跟着变。
运行结果如下所示:
3、引用类型按值传递
可以看出引用类型按值传递的时候,两个变量在堆当中的地址是一样的,故改变其中一个对象的属性另外一个对象会受到影响。
运行结果如下所示:
还有一种情况是变量p2在Test方法内部被重新初始化了,如下所示:
可以发现此时两个变量的栈地址和堆地址都不一样,故两个变量互不影响。
运行结果如下所示:
4、引用类型按引用传递
可以发现引用类型按引用传递的时候(加了ref),两个变量的栈地址和堆地址都是一样的,故两个变量值改变时会互相影响。
运行结果如下所示:
同样的还有一种情况是变量p2在Test方法内部被重新初始化了,如下所示:
从即时窗口中可以发现,当变量p2被重新初始化后变量p1的堆地址也跟着p2变化了,故此时改变其中一个变量的值则另外一个变量也会受到影响,这点和引用类型按值传递有很大不同。
运行结果如下所示:
至此本文就全部介绍完了,如果觉得对您有所启发请记得点个赞哦!!!
此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/13700316.html
版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!