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

一,c#中的值类型和引用类型

     

什么是值类型,什么是引用类型

 

概念:值类型直接存储其值,而引用类型存储对其值的引用。部署:托管堆上部署了所有引用类型。

 

引用类型:基类为Objcet

值类型:均隐式派生自System.ValueType:

 

值类型:

byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。

引用类型:

1、 类;

2、 接口;

3、 委托;

4、 数组;

5、 内置object;

6、 内置string;



而每种类型都可以细分为如下类型:

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



  • 值类型变量声明后,不管是否已经赋值,编译器为其分配内存。
  • 引用类型当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
  • 值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。
  • 引用类型的对象总是在进程堆中分配(动态分配)。

我们来看下面一段代码:

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

输出结果:

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

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

值类型在栈内分配空间大小因变量类型而异;

引用类型在栈内的空间大小相同;


二 特例:数组

考虑数组:

int[] reference = new int[100];

根据定义,数组都是引用类型,所以int数组当然是引用类型(即reference.GetType().IsValueType为false)。

而int数组的元素都是int,根据定义,int是值类型(即reference[i].GetType().IsValueType为true)。那么引用类型数组中的值类型元素究竟位于栈还是堆?

如果用WinDbg去看reference[i]在内存中的具体位置,就会发现它们并不在栈上,而是在托管堆上。

实际上,对于数组:

TestType[] testTypes = new TestType[100];

如果TestType是值类型,则会一次在托管堆上为100个值类型的元素分配存储空间,并自动初始化这100个元素,将这100个元素存储到这块内存里。

如果TestType是引用类型,则会先在托管堆为testTypes分配一次空间,并且这时不会自动初始化任何元素(即testTypes[i]均为null)。等到以后有代码初始化某个元素的时候,这个引用类型元素的存储空间才会被分配在托管堆上。




from:https://www.cnblogs.com/woaixiaozhi/p/5116137.html

         https://www.cnblogs.com/bakuhert/articles/5878086.html