一、基本概念

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

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

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

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

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

二、代码展示

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

内存分配情况如下图:

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

修改代码如下:

内存分配情况:

由上图可以知:

object obj=”abc”;
string i=(string)obj;

值类型和引用类型储的位置不一样
如果是引用类型,当两个对象指向同一个地方,修改某一个的时候,其它对象的值会发生改变

注意点:

1、值类型变量做为局部变量时,该实例将被创建在堆栈上;而如果值类型变量作为类型的成员变量时,它将作为类型实例数据的一部分,同该类型的其他字段都保存在托管堆上。

2、引用类型变量数据保存在托管堆上,但是根据实例的大小有所区别:当实例的大小小于85000Byte时实例将创建在GC堆上;当实例大小>=85000byte时,则该实例创建在LOH(Large Object Heap)堆上。

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 = ; //提领指针
v1.x = ; //在栈上修改
Console.WriteLine(r1.x); //显示5
Console.WriteLine(v1.x); //显示5 SomeRef r2 =r1; //只复制引用(指针)
SomeVal v2 =v1; //在栈上分配并赋值成员
r1.x = ; //r1.x和r2.x都会修改
v1.x = ; //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();
}
}
}

图片上的代码

栈stack(先进后出)是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;

 堆heap(队列优先,先进先出)是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

二、值类型装箱、拆箱

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

int  i=1;
object obj=(object)i;

装箱时到底发生的事情:

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

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

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

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

object obj=”1”;
int i=(int)obj;

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

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

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

string str = "joye.net" + ;   //需要将26装箱为string类型
string str1 = "joye.net" + .ToString(); //tostring后不需要装箱

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

三、参考资料

  《深入理解C#》第二版

  《CLR VIA C#》第四版

  《C# 高级编程》第四版

  还有很多网络上的文章,就不一一例举了

C# 值类型和引用类型的更多相关文章

  1. C# - 值类型、引用类型&走出误区,容易错误的说法

    1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...

  2. 【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

    为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...

  3. 图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  4. c# 我所理解的 值类型 and 引用类型

    一直以来对于值类型和引用类型都只是一个模糊的概念,趁最近有空深入理解了下. 先说说值类型,在msdn上是这样介绍值类型的. 意思就是值类型直接包含值. 变量引用的位置就是值所在内存中实际存储的位置,所 ...

  5. JAVA初学(1):值类型和引用类型的区别

    JAVA值类型和引用类型的区别(转)                                                          [定义] 引用类型表示你操作的数据是同一个,也就 ...

  6. C#类和接口、虚方法和抽象方法及值类型和引用类型的区别

    1.C#类和接口的区别接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!而类是负责功能的具体实现!在类中也有抽象类的定义,抽象类与接口的区别在于:抽象类是一个不完全的类,类里面有抽 ...

  7. .NET面试题解析(01)-值类型与引用类型

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还 ...

  8. Emit学习(2) - IL - 值类型和引用类型(补)

    上周末回家去享受生活了, 工作是为了更好的生活嘛, 所以我把生活, 工作分的比较开. 这几天不是很忙, 在学习工作技能的同时, 发点博文, 也算是做一个学习笔记 上篇中, 贴出的地址里面那位哥, 也有 ...

  9. Swift 值类型和引用类型

    Swift中的类型分为两类:一,值类型(value types),每个值类型的实例都拥有各自唯一的数据,通常它们是结构体,枚举或元组:二,引用类型(reference types),引用类型的实例共享 ...

随机推荐

  1. InnoDB源码分析--事务日志(一)

    原创文章,转载请注明原文链接(http://www.cnblogs.com/wingsless/p/5705314.html) 在之前的文章<InnoDB的WAL方式学习>(http:// ...

  2. oracle存储过程、函数、序列、包

    一. 存储过程 1. 语法 create or replace procedure procedureName(seqName varchar2) is /*声明变量*/ n ); cursor cu ...

  3. windows下使用mysql双机热备功能

    一. 准备工作 1. 准备两台服务器(电脑),接入局域网中,使互相ping得通对方 2. 两台服务器都安装mysql-server-5.1,必须保证mysql的版本一致 3. 假设,服务器A:192. ...

  4. js判断游览器是移动端还是PC端

    js判断网页游览器是移动端还是PC端 <script type="text/javascript"> function browserRedirect() { var ...

  5. x01.os.16: 添加功能

    准备工作  1.确保是 win xp,如是 win 8,运行 nasm 需按提示同意安装组件.  2.确保 src 和 z_tools 在同一目录下,nasm 已包含在 z_tools 文件夹中.  ...

  6. Qt使用自带的windeployqt 生成exe来发布软件

    集成开发环境 QtCreator 目前生成图形界面程序 exe 大致可以分为两类:Qt Widgets Application  和 Qt Quick Application.下面分别介绍这两类exe ...

  7. RedHat 6.2 Linux修改yum源免费使用CentOS源

    在没有光盘的情况,需要安装软件包,就要用到共网的yum源来安装了. RedHat linux 默认是安装了yum软件的,但是由于激活认证的原因让redhat无法直接进行yum安装一些软件,如果我们需要 ...

  8. 【CSS】使用CSS选择器

    CCS选择器的作用是找出某类元素.以便使我们使用style元素或者外部样式表对这类元素设置样式. 1.使用CSS基本选择器 有些选择器使用起来非常简单,我们把这部分选择器称为基本选择器(basic s ...

  9. 平面直接坐标系线段相交问题(小Q(钟神)的问题)

    [问题描述] 小 Q 对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目:首先,小 Q 会在?轴正半轴和?轴正半轴分别挑选?个点.随后,他将 ...

  10. [No000005]C#注册表操作,创建,删除,修改,判断节点是否存在

    //用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和删除.判断注册表项是否存在.判断键值是否存在. //准备工作: //1:要操作注册表 ...