zoukankan      html  css  js  c++  java
  • 深入了解装箱和拆箱

     我们将通过实际的例子以及ILDASM.exe工具去查看装箱和拆箱的过程(至于ILDASM.EXE的用法请查看MicroSoft的帮助).

        一::我们想看下装箱和拆箱的对象

            装箱:值类型=>引用类型.

            拆箱:引用类型=>值类型

            所以我们看到再整个装箱和拆箱的过程中设计到两种类型.值类型(原类型(SbyteByteShortUshortIntUintLongUlongCharFloatDoubleBoolDecimal)、枚举(enum)、结构(struct).引用类型(类,接口,数组,委托,字符串等).

        实例1:阅读下面的程序,说出程序中的装箱和拆箱操作.

    using System;
    class sample1
    {
      
    public static void Main()
      {
        
    int i=10;
        
    object obj=i;
        Console.WriteLine(i
    +","+(int)obj);
      }

        答:实例1中进行了3次装箱和1次拆箱.第一次object obj=i;i装箱;而Console.WriteLine方法用的参数是String对象,因此,i+","+(int)obj中,i需要进行一次装箱(转换成String对象)(int)objobj对象拆箱成值类型,而根据WriteLine方法,比较将(int)obj值装箱成引用类型。说起来这么复杂,大家看看ildasm.exe的反汇编结果(如下图),数一下Box和Unbox就很容易理解了。


    如果我们将Console.WriteLine(i+","+(int)obj);改为:    Console.WriteLine(obj+","+obj); 得到同样的效果,而其中仅进行一次装箱操作(object obj=i;),虽然这个程序并没有实际的意义,但是加深我们对概念的理解。

       实例二:我这里我列出两个例子,装箱和拆箱对程序性能的影响

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;

    namespace Boxandunbox
    {
        
    class Sample
        {
            
    public static void Main()
            {
                
    int count;
                DateTime startTime 
    = DateTime.Now;
                ArrayList myArrayList 
    = new ArrayList();

                
    // 重复5次测试
                for (int i = 5; i > 0; i--)
                {

                    myArrayList.Clear();
                    
    // 将值类型加入myArrayList数组
                    for (count = 0; count < 5000000; count++)
                        myArrayList.Add(count); 
    //装箱

                    
    // 重新得到值
                    int j;
                    
    for (count = 0; count < 5000000; count++)

                        j 
    = (int)myArrayList[count];  //拆箱
                }
                
    // 打印结果
                DateTime endTime = DateTime.Now;
                Console.WriteLine(
    "Start: {0}\nEnd: {1}\nSpend: {2}",
                startTime, endTime, endTime 
    - startTime);
                Console.WriteLine(
    "Push ENTER to return commandline");
                Console.ReadLine();
            }
        }
    }

    请看运行结果图

     

     

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;

    namespace Boxandunbox
    {
        
    class Sample
        {
            
    public static void Main()
            {
                
    //Code1#region //Code1
                
    //int count;
                
    //DateTime startTime = DateTime.Now;
                
    //ArrayList myArrayList = new ArrayList();

                
    /**///// 重复5次测试
                //for (int i = 5; i > 0; i--)
                
    //{

                
    //    myArrayList.Clear();
                
    //    // 将值类型加入myArrayList数组
                
    //    for (count = 0; count < 5000000; count++)
                
    //        myArrayList.Add(count); //装箱

                
    //    // 重新得到值
                
    //    int j;
                
    //    for (count = 0; count < 5000000; count++)

                
    //        j = (int)myArrayList[count];  //拆箱
                
    //}
                /**///// 打印结果
                //DateTime endTime = DateTime.Now;
                
    //Console.WriteLine("Start: {0}\nEnd: {1}\nSpend: {2}",
                
    //startTime, endTime, endTime - startTime);
                
    //Console.WriteLine("Push ENTER to return commandline");
                
    //Console.ReadLine();
        #endregion
                
    int count;

                ArrayList myArrayList 
    = new ArrayList();

                
    // 构造 5000000 字符串数组
                string[] strList = new string[5000000];
                
    for (count = 0; count < 5000000; count++)
                    strList[count] 
    = count.ToString();

                
    // 重复5次测试
                DateTime startTime = DateTime.Now;
                
    for (int i = 5; i > 0; i--)
                {
                    myArrayList.Clear();
                    
    // 将值类型加入myArrayList数组
                    for (count = 0; count < 5000000; count++)
                        myArrayList.Add(strList[count]);
                    
    // 重新得到值
                    string s;
                    
    for (count = 0; count < 5000000; count++)
                        s 
    = (string)myArrayList[count];
                }
                
    // 打印结果
                DateTime endTime = DateTime.Now;
                Console.WriteLine(
    "Start: {0}\nEnd: {1}\nSpend: {2}",
                startTime, endTime, endTime 
    - startTime);
                Console.WriteLine(
    "Push ENTER to return commandline");
                Console.ReadLine();
            }
        }
    }

    结果如下图

     

    实例二说明:实例二(1)的循环中包含一次装箱和一次拆箱(这里我均忽略两个程序打印时的装箱操作),实例二(2)则没有相应的操作。当循环次数足够大的时候,性能差异是明显的。再次提醒你别忘了ILDASM.EXE这个工具哦,分别看看,才能一窥程序的本质。否则,粗看程序实例二(2)实例二(1)多了不少代码,更多了一个50000005M)的循环,就以为实例二(2)会更慢............
     

  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/purplefox2008/p/1808951.html
Copyright © 2011-2022 走看看