C#基础——引用类型(reference type)与值类型(value type)

参考博客

一.引言

参考博客

关于value type和reference type 最为常见的问题就是class和struct的区别。

class是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、构造函数、索引器、操作符等。在.NET中,所有的class最终继承自System.Object 类,因此是一种引用类型,也就是说,new一个类的实例时,在stack上存放该实例在managed heap中的地址,而实例的值保存在managed heap中。具有面向对象的拓展优势,适合将用于定义应用程序行为的类型设计。

struct是用于将一组相关的变量组织为一个单一的变量实体。所有的struct都继承自System.ValueType,因此是一种值类型,也就是说,struct实例在创建分配在线程的stack上,它本身存储了值,所以在使用struct时,我们可以将其当作int、char这样的基本类型对待。具有性能优势,适合用于底层数据存储的类型设计。

所以两者的区别就很明显了:

1.class是reference type所以可以设置为NULL,但struct是值类型,所以不可以设置为NULL。

2.实例化一个class,它将创建在堆上。而实例化一个struct,它将创建在栈上。

3.使用的是class的应用,直接使用struct

4.传递参数时,class作为参数,传递的是一个引用,struct传递的是值

5.structs不可以有初始化器,class可以有。

6.class可以有明显的无参数构造函数,但struct不可以

7.使用class前需要new关键字来实例化,struct不需要

8.class支持继承和多态,struct不支持,但struct可以和类一样实现接口

9.struct不支持继承,所以不能用protected、protected internal修饰

10.class的构造函数不必初始化全部字段,但struct的构造函数必须初始化全部字段

11.class可以定义析构函数,但struct不可以

12.class比较适合大的和复杂的数据,struct适用于作为经常使用的一些数据组合成的新类型

二.reference type & value type

参考博客

value type:value type变量声明后,不管是否已经赋值,编译器为其分配内存,在线程stack上分配(静态分配)。所有的value type均隐式派生于System.ValueType(System.ValueType直接派生于System.Object),均有一个隐式的默认构造函数来初始化该类型的默认值。所有的value type都是seal(密封)的,无法派生出新的value type。Value Type重写了Equals()方法,从而对值类型按照实例的值来比较,而不是用引用地址来比较。


reference type:声明时,只在stack中分配一小片内存用于容纳一个地址,而此时并没有为其分配heap上的内存空间,当使用new创建一个实例时,分配heap上的空间,并把heap上空间的地址保存到stack上分配的小片空间中。总是在进程heap中分配(动态分配)


C#的基本数据类型都以平台无关的方式来定义。C#的预定义类型并没有内置于语言中,而是内置于.NET Framework中。.NET使用通用类型系统(CTS)定义了可以在中间语言(IL)中使用的预定义数据类型,所有面向.NET的语言都最终被编译为IL,即编译为基于CTS类型的代码。

例如,在C#中声明一个int变量时,声明的实际上是CTS中System.Int32的一个实例。这具有重要的意义:

  • 确保IL上的强制类型安全;
  • 实现了不同.NET语言的互操作性;
  • 所有的数据类型都是对象。它们可以有方法,属性,等。

使用场合:

value Type:只需一次分配即可,适用于主要职责是数据存储、共有接口完全由一些数据成员存取属性定义、永远不可能有子类、不具有多态行为的类型。

reference type:消耗更多的时间,造成更多的内存碎片,适用于定义应用程序的行为。

三.stack与heap

Value Type部署在stack上,reference部署在managed heap上。

托管堆上部署了所有引用类型。

结构体不要求在堆上分配内存。

对于第二句话的理解:

1.数组

数组是reference type,int[] A= new int[100] 但是,数组中元素是value type,这时元素是储存在managed heap上,此时的managed heap会为100个value type的元素分配储存空间,并自动初始化;倘若数组元素是reference type,则会在managed heap先分配一次空间,但并不初始化,全部为NULL,等到以后有代码初始化某个元素的时候,这个reference type元素的存储空间才会被分配在managed heap 上。

2.类型嵌套

引用类型包含值类型,以及值类型包含引用类型的情况规律是:

  • 引用类型部署在托管堆上;
  • 值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。

堆栈(stack)和托管堆(managed heap)都在进程的虚拟内存中。

managed heap (托管堆):在垃圾回收器GC的控制下工作

stack:stack的内存是自动释放的,由高内存地址指向低内存地址填充,工作方式为先分配内存的变量后释放,从上向下填充,从下向上释放,这样保证了堆栈的先进后出原则不与变量的生命周期冲突。

四:Unity相关

vector(向量)是value type,原因很简单,vector的功能很简单,用来储存一个向量数据而已,性能是这个类型最大的考量,使用struct更加高效。

string(字符串)是reference type,原因是string类型很大,需要储存在heap中。参考博客

猜你喜欢

转载自blog.csdn.net/vestlee/article/details/80800371
今日推荐