zoukankan      html  css  js  c++  java
  • 装箱和拆箱

    1.装箱与拆箱

    装箱是指将值类型(如 int ,或自定义的值类型等)转换成 object 或者接口类型的一个过程。当 CLR 对值类型进行装箱时,会将该值包装为 System.Object 类型,再将包装后的对象存储在堆上。 拆箱就是从对象中提取对应的值类型的一个过程。装拆箱其实就是值类型和引用类型两者之间的类型转换操作。

    装箱的过程是隐式的,而拆箱的过程必定是显式的,其大致用法如下:

    static void Main(string[] args)
    {
        int a = 1;
        object o = a; // 装箱
        int b = (int)o; // 拆箱
    }

    简单来讲,装箱就是将一个值类型转换为引用类型,拆箱就是将一个引用类型转换为值类型。那么什么是值类型和引用类型呢?

    2.值类型与引用类型

    在 C# 中存在着两种类型,值类型和引用类型,两者的定义如下:

    • 引用类型:所有的类,包括接口、委托;string是特殊的引用类型(只读);数组;已装箱值类型(object)
    • 值类型:内置值类型;用户自定义值类型(结构);枚举

    值类型和引用类型在内存中的分配:

    • 堆(Heap):地址从低到高分配,所有引用类型的对象分配在托管堆上
    • 栈(Stack):地址从高到低分配,所有的值类型及引用类型的引用分配在栈上

    大致的堆栈图如下图所示:

    3.装箱拆箱过程

    3.1 装箱

    装箱就是值类型到 object 类型或者到该值类型所实现的接口类型所实现的一个隐式转换过程(可显式)。装箱的时候会在堆中自动创建一个对象实例,然后将该值复制到新对象内。

    var i = 123;    //System.Int32
    
    //对 i 装箱(隐式)进对象 o
    object o = i;

    从图可知,对象 o 存的是地址引用,指向的是堆上的值,这个值的类型和变量 i 一样,也是 int 类型,值(123)也就是从变量 i 复制过来的一个副本值而已。

    3.2 拆箱

    拆箱是从 object 类型到值类型,或从接口类型到实现该接口的值类型的显式转换的一个过程。拆箱时检查对象实例,确保它是给定值类型的一个装箱值后,再将该值从实例复制到值类型变量中。

    int i = 123;      // 值类型
    object o = i;     // 装箱
    int j = (int)o;   // 拆箱

    要在运行时成功拆箱值类型,被拆箱的项必须是对一个对象的引用,该对象是先前通过装箱该值类型的实例创建的。

    拆箱时需要注意,转换出现异常的情形:

    虽然,decimal 类型可以直接强转为 int 类型,但从调式的结果来看,拆箱时是会引发“转换无效”的异常。要记住,拆箱时强转的值类型,应与装箱时的值类型一致。

  • 相关阅读:
    数据库使用时应该避开的坑
    Linux 命令 curl 的用法及参数解析
    分析 Redis 是否适合作为消息队列
    WEB框架对比——Django、Flask、FastAPI
    视频下载神器——you-get
    QtScrcpy——开源的电脑控制手机(投屏+控制)软件
    Python库大全
    Docker 清理数据卷 volumes
    报错解决——失败
    微信电脑端多开
  • 原文地址:https://www.cnblogs.com/jizhiqiliao/p/9811524.html
Copyright © 2011-2022 走看看