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

 更新时间:2016年06月17日 08:54:23   作者:Joye.Net  
在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。下面我们来简单谈谈C#中的值类型和引用类型

一、基本概念

C#只有两种数据类型:值类型和引用类型

值类型在线程栈分配空间,引用类型在托管堆分配空间

值类型转为引用类型称成为装箱,引用类型转为值类型称为拆箱

以下是值类型和引用类型对照表

从上图可以简单看出:string,Object,数组,class是引用类型,简单类型,枚举,结构是值类型。

二、代码展示

定义一个类和结构调用赋值

内存分配情况如下图:

从这张图可以看出,class实例化出来的对象,指向了内存堆中分配的空间;truct实例化出来的对象,是在内存栈中分配。

修改代码如下:

内存分配情况:

由上图可以知:

复制代码 代码如下:

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();
    }
  }
}

三、值类型装箱、拆箱

1、装箱:就是将值类型的数据打包到引用类型的实例中(比如将string类型的值abc赋给object对象obj)

复制代码 代码如下:
String i=”abc”;
object obj=(object)i;

装箱时到底发生的事情:

1)、在托管堆中分配内存。分配的内存量是值类型各字段所需的内存量,还要加上托管堆所有对象都有的两个额外成员(类型对象指针和同步块索引)所需的内存量

2)、值类型的字段复制到新分配的堆内存

3)、返回对象地址,现在该地址是对象引用;值类型成了引用类型

2、拆箱:就是从引用数据中提取值类型(比如将object对象obj的值赋给string类型的变量i)

复制代码 代码如下:
object obj=”abc”;
string i=(string)obj;

拆箱不是装箱过程倒过来,拆箱的代价爱比装箱低的多,拆箱是获取指针的过程,该指针指向包含在一个对象中的原始值类型。

拆箱后将堆中的字段包含的值复制栈的值类型实例中。

3、值类型变为引用类型不一定要装箱,例如:

复制代码 代码如下:
string str = "joye.net" + 26; //需要将26装箱为string类型
string str1 = "joye.net" + 26.ToString(); //tostring后不需要装箱

感兴趣的可以用IL看一下。

相关文章

  • 深入多线程之:双向信号与竞赛的用法分析

    深入多线程之:双向信号与竞赛的用法分析

    本篇文章是对双向信号与竞赛的用法进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • C#之WinForm WebBrowser实用技巧汇总

    C#之WinForm WebBrowser实用技巧汇总

    这篇文章主要介绍了C#之WinForm WebBrowser实用技巧汇总,包括常见的各种设置及信息获取等,需要的朋友可以参考下
    2014-08-08
  • c# 文件操作(移动,复制,重命名)

    c# 文件操作(移动,复制,重命名)

    这篇文章主要介绍了c# 如何对文件操作(移动,复制,重命名),帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-12-12
  • UnityShader实现百叶窗效果

    UnityShader实现百叶窗效果

    这篇文章主要为大家详细介绍了UnityShader实现百叶窗效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • 如何在C# 中使用 FFmpeg.NET

    如何在C# 中使用 FFmpeg.NET

    这篇文章主要介绍了如何在C# 中使用 FFmpeg.NET,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#开发Windows窗体应用程序的简单操作步骤

    C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • C# 操作符之三元操作符浅析

    C# 操作符之三元操作符浅析

    C# 操作符之三元操作符“?:”是如何使用的呢?C# 操作符之三元操作符“?:”需要注意的是什么呢?那么本文就向你简单介绍C# 操作符之三元操作符“?:”的基本情况。
    2011-02-02
  • C#生成XML的三种途径小结

    C#生成XML的三种途径小结

    为了全面,这里都将XML保存到文件中,有三种生成XML的方式,需要的朋友可以参考下
    2013-05-05
  • 浅析C#的复制和克隆

    浅析C#的复制和克隆

    这篇文章主要介绍了浅析C#的复制和克隆,需要的朋友可以参考下
    2014-07-07
  • C#静态方法的使用

    C#静态方法的使用

    这篇文章介绍了C#静态方法的使用,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04

最新评论