当前位置:首页 > Windows程序 > 正文

1、装箱和拆箱,枚举的ToString浅析

2021-03-21 Windows程序

  编写程序时,也许你不经意间,就不知不觉的使程序代码,发生了装箱和拆箱,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环、网络程序(不断请求处理的)等这些时候,减少装箱和拆箱,是优化程序提高效率的一种途径。不仅跬步,无以至千里,不积小流,无以至江河。优化从点点滴滴做起。

一、装箱拆箱概念:

  这里是官方定义:

  装箱:值类型→引用类型

  拆箱:引用类型→值类型

二、为什么说装箱,拆箱消耗资源(内存、cpu)?

  2.1 图说装箱、拆箱

    

技术分享

                    

技术分享

    说明:装箱。值类型存放于内存栈上,引用类型存放于内存对上。如果将已定义好的值类型(栈上的数据)修改至引用类型(堆上),

  2.2 图文说 装箱过程

    值类型存储(没有堆什么事):                             引用类型存储(栈中存储的是,堆中对象的地址,堆中是实际对象)

    

技术分享

      

技术分享

    这时如果,将值类型变成引用类型,存储的位置发生变化,发生了装箱,而且为了拆箱,现在引用类型的存储模式也不仅仅是以上引用类型的存储模型了,值类型的类型也会进行相应的存储,以方便在拆箱时候,转换成相应装箱时的类型。

    这样可以看出,装箱,其实比你直接定义成一个引用类型,给家消耗了内存,以及增加了计算量(消耗了cpu)。这是原理级别的解释,跟深入的,我也不太清除。只能分析到CLR这一步。

三、浅谈ToString()

  估计大家都知道,C#所有的类型基类(父类)均是Object,而Object中,提供的能叫子类继承的方法就那么几个,virtual 的ToString就是其中之一,所以说,c#中所有的类型均有这个ToString方法。下面就浅谈一下ToString方法在装箱拆箱中的一二。

  3.1 针对普通值类型

    以Int32为例(Struct)

      int a=123;       string b=a.ToString();

        请问这是发生装箱了吗?

      答:值类型→引用类型,oh,装箱!!

      解答:只单纯的看装箱定义,这确实符合装箱的定义。但是,别忘记了ToString是基类的虚方法,子类是否对其有重写。

        int 的 户口祖籍

        int(C#语言)→Int32(CLR,oh是个结构,struct)

          →extends System.ValueType(查看IL代码,发现了)→extends System.Object(这是终极祖宗啊!这里有ToString啊)

        这是Int32中对ToString方法的重写:

            public override string ToString() { return Number.FormatInt32(this, null, NumberFormatInfo.CurrentInfo);}

        接下来就是内部的实现了,我去,看不到了啊?怎么办?

      对了编写代码,查看IL代码。

      

技术分享

      可以看出这里没有发生装箱啊!具体的深入内部实现可以借助反编译工具,查看,如ILSpy、reflecter、ILdasm等。

  

  3.2枚举类型

    那么所有的值类型是不是使用Tostring方法,均不涉及装箱操作呢?这个也不尽然,可是尝试一下枚举类型。

    枚举类型,是一个值类型。

    示例:

      enum TestEnum { Test1, Test2   }

      string test = TestEnum.Test1.ToString(); //这句话是否发生装箱操作

  

    3.2.1 内部原理

      首先查看枚举中的ToString方法,这里重写了ToString方法

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/64891.html