源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2022-12-13 00:10 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:浅谈C#中的值类型和引用类型
[b]一、基本概念[/b] C#只有两种数据类型:值类型和引用类型 值类型在线程栈分配空间,引用类型在托管堆分配空间 值类型转为引用类型称成为装箱,引用类型转为值类型称为拆箱 以下是值类型和引用类型对照表 [img]http://files.jb51.net/file_images/article/201606/201606170845181.jpg[/img] 从上图可以简单看出:string,Object,数组,class是引用类型,简单类型,枚举,结构是值类型。 [b]二、代码展示[/b] 定义一个类和结构调用赋值 [img]http://files.jb51.net/file_images/article/201606/201606170845182.png[/img] 内存分配情况如下图: [img]http://files.jb51.net/file_images/article/201606/201606170845183.png[/img] 从这张图可以看出,class实例化出来的对象,指向了内存堆中分配的空间;truct实例化出来的对象,是在内存栈中分配。 修改代码如下: [img]http://files.jb51.net/file_images/article/201606/201606170845184.png[/img] 内存分配情况: [img]http://files.jb51.net/file_images/article/201606/201606170845185.png[/img] 由上图可以知:
[u]复制代码[/u] 代码如下:
object obj=”abc”; string i=(string)obj;
值类型和引用类型储的位置不一样 如果是引用类型,当两个对象指向同一个地方,修改某一个的时候,其它对象的值会发生改变
using System;

namespace ConsoleApplication2
{
  //引用类型(因为‘class')
  public class SomeRef
  {
    public int x { get; set; }
  }
  //值类型(因为‘struct')
  public struct SomeVal
  {
    public int x{ get; set; }
  }

  class Program
  {
    static void Main(string[] args)
    {
      SomeRef r1=new SomeRef(); //在堆上分配
      SomeVal v1 = new SomeVal();//在栈上分配
      r1.x = 5;    //提领指针
      v1.x = 5;    //在栈上修改
      Console.WriteLine(r1.x); //显示5 
      Console.WriteLine(v1.x); //显示5

      SomeRef r2 =r1; //只复制引用(指针)
      SomeVal v2 =v1; //在栈上分配并赋值成员
      r1.x = 8;    //r1.x和r2.x都会修改
      v1.x = 8;    //v1.x会更改,v2.x不会

      Console.WriteLine(r1.x); //显示8 
      Console.WriteLine(r2.x); //显示8 
      Console.WriteLine(v1.x); //显示8
      Console.WriteLine(v2.x); //显示5

      Console.ReadKey();
    }
  }
}
[b]三、值类型装箱、拆箱[/b] 1、装箱:就是将值类型的数据打包到引用类型的实例中(比如将string类型的值abc赋给object对象obj)
[u]复制代码[/u] 代码如下:
String i=”abc”; object obj=(object)i;
装箱时到底发生的事情: 1)、在托管堆中分配内存。分配的内存量是值类型各字段所需的内存量,还要加上托管堆所有对象都有的两个额外成员(类型对象指针和同步块索引)所需的内存量 2)、值类型的字段复制到新分配的堆内存 3)、返回对象地址,现在该地址是对象引用;值类型成了引用类型 2、拆箱:就是从引用数据中提取值类型(比如将object对象obj的值赋给string类型的变量i)
[u]复制代码[/u] 代码如下:
object obj=”abc”; string i=(string)obj;
拆箱不是装箱过程倒过来,拆箱的代价爱比装箱低的多,拆箱是获取指针的过程,该指针指向包含在一个对象中的原始值类型。 拆箱后将堆中的字段包含的值复制栈的值类型实例中。 3、值类型变为引用类型不一定要装箱,例如:
[u]复制代码[/u] 代码如下:
string str = "joye.net" + 26; //需要将26装箱为string类型 string str1 = "joye.net" + 26.ToString(); //tostring后不需要装箱
感兴趣的可以用IL看一下。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部