欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > 内容正文

Windows Phone 开发起步之旅之二 C#中的值类型和引用类型

来源: 开发者 投稿于  被查看 11213 次 评论:101

Windows Phone 开发起步之旅之二 C#中的值类型和引用类型


  今天和大家分享下本人也说不清楚的一个C#基础知识,我说不清楚,所以我才想把它总结一下,以帮助我自己理解这个知识上的盲点,顺便也和同我一样不是很清楚的人一起学习下。

   一说起来C#中的数据类型有哪些,大部分的人都知道值类型和引用类型,两者的区别呢,我是说不全,下面先给出他们的定义吧,咱们再一一解释那他们的区别。

 

1.两种类型的介绍

1.值类型(value type)

1)定义

  一种由类型的实际值表示的数据类型。如果向一个变量分配值类型,则该变量将被赋以全新的值副本。(这与引用类型不同,在引用类型中,赋值时不创建副本。)值类型通常创建在方法的栈帧上,而不是在垃圾回收堆中。可以对值类型进行装箱,这是一个创建相应引用类型的过程。

  C#中的值类型包括结构类型和枚举类型两大类以及char、byte、long、int、float和double等简单类型,值类型继承自System.ValueType,值类型不能为空(null)。 值类型包括三大类型:简单类型、结构类型、枚举类型。  

2)参考文章

http://msdn.microsoft.com/zh-cn/library/s1ax56ch.aspx  

2.引用类型(reference type)

1)定义

  引用类型 由类型的实际值引用(类似于指针)表示的数据类型。如果为某个变量分配一个引用类型,则该变量将引用(或“指向”)原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。  

2)参考文章

http://msdn.microsoft.com/zh-cn/library/490f96s2.aspx  

2.两者的区别

 通过一个表格来对比下他们的区别

 

补充说明:

  1.值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。因此,一个值类型变量就永远不会影响到其他的值类型变量,而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。

  2.从内存分配上来看,值类型通常分配在线程的堆栈上,作用域结束时,所占空间自行释放,效率高,无需进行地址转换,而引用类型通常分配在托管堆上,由GC来控制其回收,需要进行地址转换,效率降低,这也正是c#需要定义两种数据类型的原因之一。

  3.值类型均隐式派生自System.ValueType,而System.ValueType又直接派生于System.Object,每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,注意所有的值类型都是密封(sealed)的,所以无法派生出新的值类型。而且System.ValueType本身是一个类类型,而不是值类型,因为它重写了object的Equals()方法,所以对值类型将按照实例的值来比较,而不是比较引用地址。

  4.C# 的统一类型系统,使得值类型可以转化为对象来处理,这就是常说的装箱和拆箱。由于装拆箱需要装建全新对象或做强制类型转换,这些操作所需时间和运算要远远大于赋值操作,因此不提倡使用它,同时也要尽量避免隐式装拆箱的发生。 

  注:栈是操作系统分配的一个连续的内存区域,用于快速访问数据。因为值类型的容量是已知的,因此它可存储在栈上。而托管堆是CLR在应用程序启动时为应用程序预留的一块连续内存区,是用于动态内存分配的内存区,引用类型的容量只有到运行时才能确定,所有用堆来存储引用类型。

嵌套类型的内存分配

对于引用类型嵌套值类型,以及值类型嵌套引用类型的情况下,内存分配可以根据以下两条规律来判断:
•    引用类型始终部署在托管堆上;
•    值类型总是分配在它声明的地方:作为字段时,跟随其所属的对象存储;作为局部变量时,存储在栈上。

 

误区

“引用类型在堆上,值类型在栈上”

这个是用问题的,这个是部分正确的说法,问题出在值类型上,正如上面对“引用类型嵌套值类型”的说明中讲的那样,值类型作为字段时,跟随其所属的对象存储,所以这个时候即便是值类型,也会被分配到堆上;只有局部变量和方法参数在栈上。

相关频道:

用户评论