.Net之值类型的装箱、拆箱

本文深入解析了.NET中值类型与引用类型之间的转换,即装箱与拆箱过程,详细介绍了装箱时内存分配及值复制的步骤,以及拆箱时的地址获取与值复制过程。通过具体代码示例,展示了不同场景下装箱与拆箱的次数差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

值类型的装箱、拆箱

值类型是一种比引用类型更加轻型的一种类型,要将值类型转为引用类型需要装箱, 装箱在.NET发生以下操作:

 

  1. 要计算值类型每个字段的所需内存量,同时因为要转换为引用类型必定要加上同步块索引和对象指针所占用的内存,再根据大小来申请内存
  2. 申请好之后当然是将所有的值赋值到托管堆中
  3. 最后返回对象的用

与其意义上相反的操作就是拆箱:将引用类型转为值类型。其中要说明的是,拆箱操作要付出的代价要比装箱却要小的多,主要为

  1. 获取对象个属性的地址
  2. 将对象值复制到栈中。

本质上是获取引用类型的指针。 

实例说明

 

  •  下面来一个小例子:
View Code 
 1 static void Main(string[] args)
 2         {
 3             First();
 4             Second();
 5         }
 6         static void First()
 7         {
 8             Int32 a = 1;
 9             object v = a;
10             a = 123;
11             Console.WriteLine(a + "," + v);
12         }
13         static void Second()
14         {
15             Int32 a = 1;
16             object v = a;
17             a = 123;
18             Console.WriteLine(a.ToString() + "," + v.ToString());
19

 

方法First和方法Second各自装箱了几次?答案为:3和1.因为 a + "," + v会调用String.Concat(Object arg[]),在First里就会发生2次装箱,而ToString返回String类型避免了装箱

  •  例子:
struct Point : IComparable
    {
        private Int32 x, y;
        public Point(Int32 _x, Int32 _y)
        {
            x = _x;
            y = _y;
        }
        public override string ToString()
        {
            return string.Format("{0},{1}", x, y);
        }
        public Int32 CompareTo(Point p)
        {
            return Math.Sign(this.x * this.x + this.y * this.y - p.x * p.x - p.y * p.y);
        }
        public Int32 CompareTo(object o)
        {
            if (this.GetType() != o.GetType())
                throw new ArgumentException("o is not point");
            else
                return CompareTo((Point)o);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Point p1 = new Point(1010);
            Point p2 = new Point(2020);
            Console.WriteLine(p1.ToString());
            Console.WriteLine(p1.GetType());
            Console.WriteLine(p1.CompareTo(p2));
            IComparable compare = p1;
            Console.WriteLine(compare.GetType());
            Console.WriteLine(p1.CompareTo(compare));
            p2 = (Point)compare;
            Console.WriteLine(p2.ToString());
        }
    }

这个例子发生了3次装箱,1次拆箱,大家用兴趣可以看看到底哪里发生装箱拆箱

转载于:https://www.cnblogs.com/CHNI/archive/2012/11/21/2781444.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值