ToString() 会发生装箱吗?
最近被问到了这个问题,我当时回答是会的,因为ToString()会把值类型转换成引用类型,所以会发生装箱。
后来总觉有些不妥当,所以查阅一些资料并参考网络上的讨论:
拆箱装箱的官方解释:
Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. When the CLR boxes a value type, it wraps the value inside a System.Object and stores it on the managed heap. Unboxing extracts the value type from the object. Boxing is implicit; unboxing is explicit. The concept of boxing and unboxing underlies the C# unified view of the type system in which a value of any type can be treated as an object.
装箱用于在托管内存中存储值类型。装箱是是值类型到object类型或到此值类型所实现的任何接口类型的隐式转换。对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。
下面是官方的几个拆箱/装箱的例子:
eg1:inti=123;objecto=i;//隐式装箱eg2:String.Concat("Answer",42,true)//42和true都会发生装箱eg3:List<object>mixedList=newList<object>();mixedList.Add("FirstGroup:");for(intj=1;j<5;j++){mixedList.Add(j);//在添加时,j先装箱}varsum=0;for(varj=1;j<5;j++){//下面的一行会发生编译错误://Operator'*'cannotbeappliedtooperandsoftype'object'and'object'.//sum+=mixedList[j]*mixedList[j]);//下面经过拆箱就不会出现上面的编译错误.sum+=(int)mixedList[j]*(int)mixedList[j];}
Note:
相对于简单的赋值而言,装箱和取消装箱过程需要进行大量的计算。对值类型进行装箱时,必须分配并构造一个新对象。取消装箱所需的强制转换也需要进行大量的计算,只是程度较轻。
更多性能的了解:https://msdn.microsoft.com/zh-cn/library/ms173196.aspx
再引入图片来在说明内存中的变化:
inti=123;objecto=i;//隐式装箱
inti=123;//avaluetypeobjecto=i;//boxingintj=(int)o;//unboxing
看值类型有没有进行拆箱,就看他有没有装换成Object或者值类型所继承的接口类型...
Int.ToString 此方法中,值类型转换成ValueType类型,不满足装箱的条件(可以查看下面IL代码),可以判定Int.ToString是没有装箱的。
.methodprivatehidebysigstaticvoidMain(string[]args)cilmanaged{.entrypoint//代码大小45(0x2d).maxstack3.localsinit([0]int32v,[1]objecto)IL_0000:nopIL_0001:ldc.i4.5IL_0002:stloc.0IL_0003:ldloc.0IL_0004:box[mscorlib]System.Int32IL_0009:stloc.1IL_000a:ldloca.svIL_000c:callinstancestring[mscorlib]System.Int32::ToString()IL_0011:ldstr","IL_0016:ldloc.1IL_0017:unbox.any[mscorlib]System.Int32IL_001c:box[mscorlib]System.Int32IL_0021:callstring[mscorlib]System.String::Concat(object,object,object)IL_0026:callvoid[mscorlib]System.Console::WriteLine(string)IL_002b:nopIL_002c:ret}//endofmethodProgram::Main
了解了上面的信息之后以后就知道下面建议用哪一个了吧:
intnum=3;//用下面的哪个呢?请思考stringnumStr=string.Format("{0}",num);stringnumStr=string.Format("{0}",num.ToString());
参考:
https://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
http://www.cnblogs.com/DebugLZQ/archive/2012/09/02/2667835.html
http://q.cnblogs.com/q/44027
http://bbs.csdn.net/topics/360191652
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。