CSharp笔记-值类型与引用类型

之前玩python的时候就有点在意但是没仔细学…只知道python是简单值传值,复杂值传引用.

C#中的值类型和引用类型

C#中的所有Object的派生类都是引用类型
byte,short,int,long,float,double,decimal,char,bool和struct统称为值类型

这里注意,结构体为值类型而类都是引用类型.

值类型和引用类型的区别

以下部分参考了知乎这篇文章并加上自己的理解

  1. 值类型的数据存储在内存的栈中,引用类型的数据存储在内存的堆中.而内存单元中只存放堆中对象的地址,因此值类型存取速度快,引用类型存取速度慢
  2. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
  3. 值类型继承自System.ValueType,引用类型继承自System.Object
  4. 栈的内存分配是自动释放;而堆在.NET中会有GC来释放
  5. 值类型没法继承,没法用接口来引用(虽然泛型+接口解决部分问题)

以下参考知乎:C# 引用类型相比于值类型意义何在? - Nanry的回答 - 知乎

百度百科引用类型的解释:

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

值类型并不是在程序启动时就全部分配在栈上的,而是一直在入栈出栈操作,所以正常情况下由于入栈出栈的操作,不会超过栈空间的限制,超过了就是引起非常内存访问了(如果是static是不是一开始就全部分配在栈上呢?)

C#的值类型就是存在栈中的.值类型是轻量级的类型,因为在大多数情况下,值类型的的实例都分配在线程栈中,因此它不受垃圾回收的控制,缓解了托管堆中的压力,减少了应用程序的垃圾回收的次数,提高性能.(栈中存的数据可以自动清理,堆中的数据要依靠GC)

顺便,有一种编程技巧极其容易因为栈空间不足而导致非常内存访问的情况,那就是递归.如果你在一个递归方法中使用了值类型,并且递归次数过多,经常会发生栈溢出的异常。

下面是两个,上面的那个答主提到的扩展阅读,以后再看
一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
栈大小和内存分部问题

顺便引出的以后再看的问题:
栈和堆
尾递归优化