zoukankan      html  css  js  c++  java
  • 脚踏实地学C#3-装箱和拆箱

    装箱:一种接受值类型的值,根据这个值在堆中创建一个完整的引用类型对象并返回对象的引用(堆地址)的隐式转换

    int i_number = 2; //在栈中声明int类型i_Number变量并初始化
    object o_number = null; //在栈中声明object类型的o_Number变量并初始化值为null,不在堆中分配内存
    o_number = i_number;   //装箱过程 如下图所示①→②→③ 
    Console.WriteLine(o_number);     
    box1


    装箱过程:1.在托管堆分配好内存,分配的内存量是值类型的字段需要的内存量(类型对象指针和同步索引块);

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

                  3.将新分配的堆地址放入栈中的变量内;

    拆箱:将装箱的对象转换为值类型的过程(显示转换)

    object o_Number = 1; //装箱
    int i_Number = (int)o_Number; //拆箱
    Console.WriteLine(i_Number);

    拆箱过程:1.获取已装箱的对象各个字段的地址;

                  2.将字段包含的值复制到值类型的实例中;

    装箱和拆箱测试

    class Program
         {
            private static void Main(string[] args)
            {
                ValueTypeTestMethod();
    	    Console.ReadKey();
            }
            private static void ValueTypeTestMethod()
            {
                const int count = 10000000;  //循环的次数
                using (new OperationTimer("List<int> Type(int)"))
                {
                    List<int> list = new List<int>();
                    for (int i = 0; i < count; i++)
                    {
                        list.Add(i);     //泛型不装箱
                        int x = list[i]; //不拆箱
                    }
                    list = null;
                }
                using (new OperationTimer("ArrayList Type(int)"))
                {
                    ArrayList arrayList = new ArrayList();
                    for (int i = 0; i < count; i++)
                    {
                        arrayList.Add(i);           //会进行装箱
                        int x = (int)arrayList[i];  //进行拆箱
                    }
                    arrayList = null;
                }
            }       
        }
        internal sealed class OperationTimer : IDisposable
        {
            private long m_StartTime;
            private string m_MSG;
            private int m_CollectionCount;
            public OperationTimer(String msg)
            {
                PrepareForOperation(); //强制垃圾回收
                m_MSG = msg;
                m_CollectionCount = GC.CollectionCount(0);
                m_StartTime = Stopwatch.GetTimestamp();
            }
            public void Dispose()
            {
                Console.WriteLine("{0,6:###.00} seconds (GC={1,3}) {2}", (Stopwatch.GetTimestamp() - m_StartTime) / (double)Stopwatch.Frequency, GC.CollectionCount(0) - m_CollectionCount, m_MSG);
            }
            private static void PrepareForOperation()
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            }
        }
        
    集合List<int>ArrayList
    时间(s)垃圾回收次数时间(s)垃圾回收次数
    64位程序 .20 3 1.37 44
    32位程序 .22 3 1.57 23

    注意:从上面测试看出List<int>和ArrayList在所耗时间和垃圾回收区别都是在很大的,所以用泛型List<int>代替ArrayList是一个很好的习惯!同时也避免在循环中大量的装箱和拆箱操作;

  • 相关阅读:
    玩转Visual Studio Editor篇
    .Net2.0的集合操作 What i know?
    Log文件压缩
    [转]比较高效地实现从两个不同数组中提取相同部分组成新的数组(只支持Int类型) [C#]
    Stream 和 Byte[]互操作
    net 2.0 中如何在线程引发的事件中控制forms controls
    C# 操作Word文档(转)
    利用Lucene.net搜索引擎进行多条件搜索的做法
    c# 添加图片水印,可以指定水印位置+生成缩略图
    SDN第一次作业
  • 原文地址:https://www.cnblogs.com/qq0827/p/3317168.html
Copyright © 2011-2022 走看看