• C#:装箱与拆箱


    装箱和拆箱概念,给值类型和引用类型相互转换搭起了一座桥梁,即:value_type值可以转换成object类型的值,反过来也可以。

    1、装箱操作:允许将vaule_type隐式地转换成reference_type。

    装箱操作发生时,一般遵循下面步骤:创建一个对象实例,将value_type值复制到这个实例里面。

    在C#语言规范中,有一个例子,可以拿来供大家理解:我们可以设想有一个泛型装箱类Box<T>,他的声明和行为如下:

    sealed class Box<T> : ValueTuple
    {
        T value;
        public Box(T t)
        {
            this.value = t;
        }
    }

    当我们进行下面一个常见的装箱操作时:

    int a = 10;
    object box = a;

    其实就可以当成:

    int a = 10;
    object box_box = new Box<int>(a);

    以上便是装箱操作的过程的拆解。我们要知道并不存在这样一个Box<T>装箱类。

    关于装箱,我们要注意一点:装箱转换隐含着“复制”概念。我们常见的从引用类型referece_type到object类型的转换,可不是装箱转换。

    下面的例子也是装箱操作,从它的输出可以看出,值类型和引用类型,转换前后其实没有关系了。

    struct MyPoint
    {
        public int x, y;
        public MyPoint(int a,int b)
        {
            this.x = a;
            this.y = b;
        }
    }
    
    private static void Main(string[] args)
    {
        MyPoint myPoint = new MyPoint(10,2);
        object point = myPoint;
        myPoint.y = 20;
        Console.WriteLine(((MyPoint)point).y);
    }

    输出结果:2;

    因为:mypoint是值类型,它赋值给point时是一种装箱操作。mypoint数值在栈内存中复制了一份放到了堆中point的实例中。操作mypoint的属性对于point对象再无任何影响。假如把MyPoint声明为class类型,那么输出结果就是20,因为此时mypoint和point引用的是同一实例。

    2、拆箱操作:也称取消装箱操作,它将reference_type类型的值显示转换成了value_type类型的值。

    拆箱操作发生时经历一下步骤:首先检查实例中是否存在给定的值类型的值,然后把这个值从实例中复制出来。

    参照在装箱操作中假想的装箱类,以下普通的拆箱操作:

    object o = 10;
    int y = (int)o;

    便等同于:

    object box = new Box<int>(10);
    int yy = ((Box<int>)box).value;//从实例中找到int类型的值value,复制给变量yy中

    可以看出:拆箱操作,经历了将值从堆内存中搬运到栈内存中的一个过程。

    总结:

    无论是装箱操作还是拆箱操作,都涉及到数据在堆和栈之间进行来回搬运,这对程序性能是一种损耗。所以在编码过程中尽量避免装箱和拆箱操作。

  • 相关阅读:
    DirectUI精髓之一 控件布局的自动缩放(弹簧特性)
    windows mobile6.5截屏工具
    实现的ATL(AtlSimpleArray)数组任意插入辅助函数
    动态库中单例一记
    ASP.NET组件设计Step by Step(4)
    Asp.net 中服务端控件事件是如何触发的
    PagesSection.EnableEventValidation 属性
    ASP.NET事件回传机制
    (服务器控件)页面框架处理回发数据的过程
    ASP.NET底层架构
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/13513626.html
Copyright © 2020-2023  润新知