CLR值类型和引用类型

知识点:引用类型、值类型、装箱、拆箱

CLR支持两种类型:引用类型和值类型。引用类型在堆上分配内存,值类型在线程栈上分配内存。值类型与引用类型如下所示:

值类型对象有两种表示形式:未装箱和已装箱。将一个值类型的变量付给另一个值类型变量,会执行一次逐字段的复制。

装箱:将一个值类型转换为一个引用类型称为装箱。装箱会发生如下操作:

1、在托管堆中分配好内存。分配的内存大小等于值类型各个字段需要的内存大小之和加上类型对象指针和同步块索引需要的内存量。

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

3、返回对象的地址。

拆箱:将一个引用类型转换为值类型,首先值类型的内存分配在线程栈中,而引用类型的内存分配在托管堆中,所以需要把引用类型中的所有字段都复制到线程栈中。CLR通过两个步骤来完成这个复制操作。

1、获取已装箱的对象中的各个字段的地址。这个过程称为拆箱。

2、将这些字段包含的值从托管堆复制到线程栈中。

通过下面例子来深入理解装箱和拆箱:

internal struct Point
    {
        private int _x, _y;

        public Point(int x = 0, int y = 0)
        {
            _x = x;
            _y = y;
        }

        public void Change(int x = 0, int y = 0)
        {
            _x = x;
            _y = y;
        }

        public override string ToString()
        {
            return string.Format("{0},{1}",_x,_y);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point p = new Point(x:1,y:1);
            Console.WriteLine(p);
            p.Change(x:2,y:2);
            Console.WriteLine(p);
            Object o = p;
            Console.WriteLine(o);
            ((Point)o).Change(x:3,y:3);
            //这个执行结果是多少?为什么?
            Console.WriteLine(o);
            Console.ReadLine();

        }
    }
时间: 2024-10-18 05:02:53

CLR值类型和引用类型的相关文章

从CLR角度来看值类型与引用类型

前言 本文中大部分示例代码来自于<CLR via C# Edition3>,并在此之上加以总结和简化,文中只是重点介绍几个比较有共性的问题,对一些细节不会做过深入的讲解. 前几天一直忙着翻译有关内存中堆和栈的问题博文<C#堆vs栈>,正是在写作本文的过程中对有些地方还是产生了很多的Why,所以就先翻译并学习了一些C/C++方面的知识,这样有助于解决CLR之外的一些困惑,希望多大家有所帮助. 对知识的理解上难免有偏差或不正确,如有疑问以及错误,还请大家回复~~~ 变量存在位置不同,导

定义类+类实例化+属性+构造函数+匿名类型var+堆与栈+GC回收机制+值类型与引用类型

为了让编程更加清晰,把程序中的功能进行模块化划分,每个模块提供特定的功能,而且每个模块都是孤立的,这种模块化编程提供了非常大的多样性,大大增加了重用代码的机会. 面向对象编程也叫做OOP编程 简单来说面向对象编程就是结构化编程,对程序中的变量结构划分,让编程更清晰. 类的概念: 类实际上是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法. 类定义了类的每个对象(称为实例)可以包含什么数据和功能. 类中的数据和函数称为类的成员:数据成员        函数成员 数据成员: 数据成员

【转】C#详解值类型和引用类型区别

通用类型系统 值类型 引用类型 值类型和引用类型在内存中的部署 1 数组 2 类型嵌套 辨明值类型和引用类型的使用场合 5 值类型和引用类型的区别小结 首先,什么是值类型,什么是引用类型? 在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中. 值类型(value type):byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型.值类型变量声明后,不管是否已经赋值,编译器为其分配内

C# 类型基础 值类型和引用类型

引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复制(Shallow Copy)和深度复制(Deep Copy),浅度复制和深度复制又是以如何复制引用类型成员来划分的.由此又引出了引用类型和值类型,以及相关的对象判等.装箱.拆箱等基础知识.索性从最基础的类型开始自底向上写起. 值类型和引用类型 先简单回顾一下C#中的类型系统.C# 中的类型一共分为

c#学习基础(2)存储、值类型和引用类型、变量

程序运行时,它的数据必须存储在内存中,数据项需要多大的内存.存储在什么地方以及如何存储都依赖该数据项的类型 运行中的程序使用两个区域来存储数据:栈和堆 栈是一个内存数组,是一个LIFO(last in first out后进先出)的数据结构 栈存储几种类型的数据: 某些类型变量的值 程序当前执行环境 传递给方法的参数 栈有以下几大特征 数据只能从栈的顶端插入和删除 把数据放到栈顶端称为入栈push 从栈顶删除数据称为出栈pop 堆是一块内存区域,在队里可以分配大块的内存用于存储某类型的数据. 与

值类型和引用类型的区别?

1.值类型和引用类型的区别? 1.将一个值类型变量赋给另一个值类型变量时,将复制包含的值.引用类型变量的赋值只复制对对象的引用(快捷方式),而不复制对象本身. 2.值类型不可能派生出新的类型:所有的值类型均隐式派生自 System.ValueType.但与引用类型相同的是,结构也可以实现接口. 3.值类型不可能包含 null 值:然而,可空类型功能允许将 null 赋给值类型. 4.每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值. 2.堆和栈的区别? 栈是编译期间就分配好的内存空间,

.Net中值类型和引用类型的区别

解析:CLR支持两种类型:值类型和引用类型.用Jeffrey Richter(<CLR via C#>作者)的话来说,"不理解引用类型和值类型区别的程序员将会把代码引入诡异的陷阱和诸多性能问题".这就要求我们正确理解和使用值类型和引用类型. 值类型包括C#的基本类型(用关键字int.char.float等来声明),结构(用struct关键字声明的类型),枚举(用enum关键字声明的类型):而引用类型包括类(用class关键字声明的类型)和委托(用delegate关键字声明的

值类型和引用类型深入理解

引言 山重水复疑无路,柳暗花明又一村,越探究越接近事物的本质.最近在学习原型模式(Prototype)时,发现原型模式本质就是对一个类原始数据的克隆,但在学习深拷贝和浅拷贝时又发现与值类型和引用类型有着千丝万缕的联系.回想好久都没有温习基础,于是就整理了值类型和引用类型的随笔,本文内容比较基础,对于想继续深入研究的同学可以查看IL更深入探究. 1.值类型(ValueType) 值类型包括:数值类型,结构体,bool型,用户定义的结构体,枚举,可空类型. 值类型的变量直接存储数据,分配在托管栈中.

C# 值类型与引用类型 (上)

1. 主要内容 类型的基本概念 值类型深入 引用类型深入 值类型与引用类型的比较及应用 2. 基本概念 C#中,变量是值还是引用仅取决于其数据类型. C#的基本数据类型都以平台无关的方式来定义,C#的预定义类型并没有内置于语言中,而是内置于.NET Framework中..NET使用通用类型系统(CTS)定义了可以在中间语言(IL)中使用的预定义数据类型,所有面向.NET的语言都最终被编译为 IL,即编译为基于CTS类型的代码, 通用类型的系统的功能: 建立一个支持跨语言集成.类型安全和高性能代