C#中的类型分为值类型和引用类型,很多初学者往往弄不清楚值类型和引用类型的区别,其实值类型和引用类型的区别是很明显的。下面先讨论一下值类型和引用类型各包括那些类型。
C#中的值类型包括基本的整型、浮点型、布尔型以及稍微复杂的结构和枚举,引用类型包括字符串、数组、类、委托以及接口等。值类型一般都是比较简单的,只包括数据的类型,当然结构是个例外,结构可以有自己的方法。引用类型一般是比较复杂的,引用类型的定义不仅包括数据,还包括一些处理数据的方法。
为了说明值类型和引用类型的区别,先要讲明白 .NET平台对内存的管理策略,.NET把内存分为堆栈和托管堆,堆栈中存储的是一些已知大小的数据,这里的大小不是数据的大小,而是需要的内存的大小,也就是说在存储数据的时候我就已经知道要分配多少内存给变量,例如,定义个整型:int i=10,编译器编译这句话的时候就知道要为i分配32位的内存,而引用类型则不同,定义的时候并不知道要为他分配多少内存,例如:string a="sunzhenxing"和string b="I am sunzhenxing"需要的内存大小显然是不一样的,因此编译器在进行编译的时候就不知道要为它分配多大的内存,这个时候就要把他们存在托管堆上,也就是说托管堆存储引用类型的数据。而在堆栈上存储指向托管堆的引用。
下面列出引用类型与值类型的区别,有了上边的基础,下面的东西就很好理解了。
值类型 | 引用类型 | |
内存分配地点 | 分配在堆栈中 | 分配在托管堆中 |
效率 | 效率高,直接利用数据 | 效率低,需要通过引用找到数据,然后进行处理 |
内存回收 | 使用完后,立即回收 | 由垃圾回收机制处理 |
函数参数与返回值 | 传递该值的副本,对副本改变不影响原来的值 | 传递该值的引用,对该对象的改变会被保留 |
类型扩展 | 不能扩展,基本值类型由.NET平台定义,结构也不能继承 |
通过继承机制容易扩展 |
最后说一下“半吊子”引用类型—string类型,之所以说string是半吊子的引用类型是因为,首先它确实的引用类型,但它却能想处理值类型一样对字符串进行处理。
例如:string str="sunzhenxing";其他的值类型都可以这样赋值(其他的引用类型用new关键字进行初始化),在比如再定义一个string str1=“ is a student”,
可以这样写str=str+str1;
虽然string类型可以这样写,但是这是以付出效率为代价的,记住任何对字符串的改变都是重新定义一个新的字符串。
文章仅供学习!