欢迎来到天天文库
浏览记录
ID:38622157
大小:148.82 KB
页数:6页
时间:2019-06-16
《品味类型——值类型与引用类型》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、本文将介绍以下内容:·类型的基本概念 ·值类型深入·引用类型深入·值类型与引用类型的比较及应用1. 引言买了新本本,忙了好几天系统,终于开始了对值类型和引用类型做个全面的讲述了,本系列开篇之时就是因为想写这个主题,才有了写个系列的想法。所以对值类型和引用类型的分析,是我最想成文的一篇,其原因是过去的学习过程中我就是从这个主题开始,喜欢以IL语言来分析执行,也喜好从底层的过程来深入了解。这对我来说,似乎是一件找到了有效提高的方法,所以想写的冲动就没有停过,旨在以有效的方式来分享所得。同时,我也认为,对值类型和引用类型的把握,
2、是理解语言基础环节的关键主题,有必要花力气来了解和深入。 2.一切从内存开始2.1基本概念从上回《第七回:品味类型---从通用类型系统开始》我们知道,CLR支持两种基本类型:值类型和引用类型。因此,还是把MSDN这张经典视图拿出来做个铺垫。 值类型(ValueType),值类型实例通常分配在线程的堆栈(stack)上,并且不包含任何指向实例数据的指针,因为变量本身就包含了其实例数据。其在MSDN的定义为值类型直接包含它们的数据,值类型的实例要么在堆栈上,要么内联在结构中。我们由上图可知,值类型主要包括简单类型、结构体类型
3、和枚举类型等。通常声明为以下类型:int、char、float、long、bool、double、struct、enum、short、byte、decimal、sbyte、uint、ulong、ushort等时,该变量即为值类型。 引用类型(ReferenceType),引用类型实例分配在托管堆(managedheap)上,变量保存了实例数据的内存引用。其在MSDN中的定义为引用类型存储对值的内存地址的引用,位于堆上。我们由上图可知,引用类型可以是自描述类型、指针类型或接口类型。而自描述类型进一步细分成数组和类类型。类类
4、型是则可以是用户定义的类、装箱的值类型和委托。通常声明为以下类型:class、interface、delegate、object、string以及其他的自定义引用类型时,该变量即为引用类型。下面简单的列出我们类型的进一步细分,数据来自MSDN,为的是给我们的概念中有清晰的类型概念,这是最基础也是最必须的内容。 2.2内存深入2.2.1.内存机制那么.NET的内存分配机制如何呢?数据在内存中的分配位置,取决于该变量的数据类型。由上可知,值类型通常分配在线程的堆栈上,而引用类型通常分配在托管堆上,由GC来控制其回收。例如,现
5、在有MyStruct和MyClass分别代表一个结构体和一个类,如下:using System;public class Test{ static void Main() { //定义值类型和引用类型,并完成初始化 MyStruct myStruct = new MyStruct(); MyClass myClass = new MyClass(); //定义另一个值类型和引用类型, //以便了解其内存区别 My
6、Struct myStruct2 = new MyStruct(); myStruct2 = myStruct; MyClass myClass2 = new MyClass(); myClass2 = myClass; }}在上述的过程中,我们分别定义了值类型变量myStruct和引用类型变量myClass,并使用new操作符完成内存分配和初始化操作,此处new的区别可以详见《第五回:深入浅出关键字---把new说透》 的论述,在此不做进一步
7、描述。而我们在此强调的是myStruct和myClass两个变量在内存分配方面的区别,还是以一个简明的图来展示一下: 我们知道,每个变量或者程序都有其堆栈,不同的变量不能共有同一个堆栈地址,因此myStruct和myStruct2在堆栈中一定占用了不同的堆栈地址,尽管经过了变量的传递,实际的内存还是分配在不同的地址上,如果我们再对myStruct2变量改变时,显然不会影响到myStruct的数据。从图中我们还可以显而易见的看出,myStruct在堆栈中包含其实例数据,而myClass在堆栈中只是保存了其实例数据的引用地址,
8、实际的数据保存在托管堆中。因此,就有可能不同的变量保存了同一地址的数据引用,当数据从一个引用类型变量传递到另一个相同类型的引用类型变量时,传递的是其引用地址而不是实际的数据,因此一个变量的改变会影响另一个变量的值。从上面的分析就可以明白的知道这样一个简单的道理:值类型和引用类型在内存中的分配区别是决定其
此文档下载收益归作者所有