第一章 C# 类型基础--->1.1 值类型和引用类型

1.1 值类型和引用类型

  C# 中的类型一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)。值类型包括了结构和枚举,引用类型则包括了类、接口、委托等。还有一种特殊的值类型,称为简单类型(Simple Type),比如 byte,int 等,这些简单类型实际上是 BCL 基类库类型的别名。比如,声明一个 int 类型,实际上是声明一个 System.Int32 结构类型。
  所有的值类型都隐式地继承自 System.ValueType 类型(注意 System.ValueType 本身是一个类类型)。之所以说是“隐式地”,是因为在 C# 代码中,是看不到这个继承关系的,这个关系只有通过 MSIL 代码才可以看到。System.ValueType 类型和所有的引用类型都继承自System.Object 基类。

说明:

  栈(stack)是一种后进先出的数据结构,在内存中,变量会被分配在栈上来进行操作。堆(heap)是用于为引用类型的实例(对象)分配空间的内存区域,在堆上创建一个对象,会将对象的地址传给栈上的变量(反过来叫变量指向此对象,或者变量引用此对象)。

1.1.1 值类型

  当声明一个值类型的变量(Variable)的时候,变量本身包含了值类型的全部字段,该变量会被分配在线程堆栈(Thread Stack)上。

1.1.2 引用类型

  当声明一个引用类型变量,并使用 new 操作符创建引用类型实例的时候,该引用类型的变量会被分配到线程栈上,变量保存了位于堆上的引用类型的实例的内存地址。变量本身不包含任何类型所定义的数据。

1.1.3 简单类型

  当使用“==”对引用类型变量进行比较的时候,比较的 是它们是否指向堆上同一个对象。,对于string类型,对它们的比较实际上比较的是值,而不是引用(string是 一种特殊的引用类型,它的特殊性在于它是不可变类型)
举个例子:

string a = "123456"; string b = "123456"; if(a == b) Console.WriteLine("a Equals to b");
1.1.4 装箱和拆箱
简单来说,装箱就是将一个值类型转换成等价的引用类型。它的过程分为这样几步:

1)在堆上为新生成的对象实例分配内存。该对象实例包含数据,但它没有名称。
2)将栈上值类型变量的值复制到堆上的对象中。
3)将堆上创建的对象的地址返回给引用类型变量。
举个例子:

int i = 1; Object boxed = i; Console.WriteLine("Boxed Point: " + boxed);
而拆箱则是将一个已装箱的引用类型转换为值类型:

需要注意的是:拆箱操作需要显示声明拆箱后转换的类型。它分为两步来完成:
1)获取已装箱的对象的地址。
2)将值从堆上的对象中复制到堆栈上的值变量中。
举个例子

int i = 1; Object boxed = i; int j; j = (int)boxed;     // 显示声明拆箱后的类型 
Console.WriteLine("UnBoxed Point: " + j);
可见,装箱和拆箱需要反复在堆上进行操作,因此,在程序中应该尽量避免无意义的装 箱和拆箱。

联系方式

个人微信

公众号_DotNet微说.jpg

你可能感兴趣的:(第一章 C# 类型基础--->1.1 值类型和引用类型)