美文网首页
第一章 C# 类型基础--->1.1 值类型和引用类型

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

作者: 张中华 | 来源:发表于2018-12-17 00:19 被阅读22次

    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);
    
    可见,装箱和拆箱需要反复在堆上进行操作,因此,在程序中应该尽量避免无意义的装 箱和拆箱。

    相关文章

      网友评论

          本文标题:第一章 C# 类型基础--->1.1 值类型和引用类型

          本文链接:https://www.haomeiwen.com/subject/rpoegxtx.html