大家好,欢迎来到IT知识分享网。
首先我们来看下值类型和引用类型都有哪些?
值类型:
-整型(byte、sbyte、long、ulong、short、ushort、int、uint);
-浮点数类型(float、double);
-十进制类型(decimal);
-字符类型(cahr);
-布尔型(bool);
-结构体(struct)以及用户自定义的结构类型;
-枚举类型(enum)
引用类型:
-类(class、object、string),即用户自定义的类,object基类,字符串类;
-接口(interface);
-数组(array);
-代理(delegate)
(如果还有遗漏,请大家告知作者补充)
接着,我们分清楚值类型和引用类型的基本数据有哪些后,再来逐步分析异同。
我们都知道,万事万物皆对象,所以,引用类型也好,值类型也好,他们的最终的父类都是Object,即System.Object,虽然这个类我们经常看不到,但不代表可以忽视,那是因为编译器已经默认不显示而已。所以此为第一个相同点。
顺着这个来说,值类型还继承了System.ValueType,也就是说,值类型的本质是继承于System.ValueType,而System.ValueType是继承于System.Object。引用类型是直接继承于System.Object。所以此为第一个不同点。
再往下,因为在System.Object的下一层,出现了不同的继承,值类型开始继承于System.ValueType,所以值类型的数据在比较的时候,直接就是值的内容的比较,而引用类型的比较则是引用(可以理解为指针)的比较(延伸内容即为equals的重写,这里不做扩展),而导致此种不同的原因则是存储的方式以及地址。
值类型在申明的时候,作为字段时,跟随其所属的变量或者实例存储,而作为局部变量是,存储在栈上,其实总的来说,值类型的存储,在其申明的时候,就直接由内存在栈上开辟了一块空间,用于存储,如果没有赋值,即为默认值,比如int的默认值为0;
而引用类型在申明的时候,也是由栈开辟了一个空间,而在实例的过程中,则由内存在堆上开辟一个空间,用于存储实例化的值,并且将该值在堆中的地址保存于之前栈的空间中。(以上都是基于新创建实例化的过程,不包含已实例化的引用类型,只是为了避免第一次接触这个概念的人混淆)。
所以第二个不同点就是存储地址不同,值类型都存储在栈上,而引用类型都存储在堆上,然后在栈上存储该值在堆中的地址,而不是真正的值。(到这里是不是有朋友有点理解为什么要重写equals方法了)
继续往下分析,由于知道了值类型和引用类型的存储位置的区别,所以,相对来说,值类型在内存管理上具有更好的效率(延伸内容为堆、栈的却别,以后会做特殊章节的讲解,这里不延伸),值类型在垃圾回收上,不由GC控制,作用域结束时,会自行释放,減少了托管堆的压力,相对的引用类型的回收,是由GC来控制的(例如通常 struct 比 class 更高
效)。
除此之外,还有其他的几个小方面,例如:
-值类型不具有多态性;而引用类型有多态性;
-值类型是密封的(sealed),因此值类型不能作为其他任何类型的基类,但是可以单继承或者多继承接口;而引用类型一般都有继承性;
-值类型变量不可为 null 值,值类型都会自行初始化为 0 值;而引用类型变量默认情况下,创建为 null 值,表示没有指向任何托管堆的引用地址。对值为 null的引用类型的任何操作,都会抛出 NullReferenceException 异常。
以上基本就是稍微大一点的方向上,值类型和引用类型的区别了,如果还有补充的话,也欢迎朋友们留言讨论。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/13065.html