拳击/拆箱和types转换有什么区别?

拳击/拆箱和types转换有什么区别?

通常,这些术语似乎可以互换使用。

拳击是指将非空值types转换为引用types或将值types转换为它实现的某个接口(比如说intIComparable<int> )。 此外,基础值types转换为可空types也是一种装箱转换。 (注意:这个主题的大部分讨论将忽略后两种types的转换。)

例如,

 int i = 5; object o = i; 

i转换为一个objecttypes的实例。

拆箱是指从objectValueType实例到非空值types的显式转换,即将接口types转换为非空值types(例如, IComparable<int>int )。 此外,可空types转换为基础types也是拆箱转换。 (注意:这个主题的大部分讨论将忽略后两种types的转换。)

例如,

 object o = (int)5; int i = (int)o; 

o的整数转换为inttypes的实例。

types转换是expression式到给定types的显式转换。 从而

 (type) expression 

显式地将expression转换为typestype的对象。

拳击和拆箱是types转换的一个子集。 拳击是将值types作为引用types(在实践中涉及将该值types的内容(从堆栈)复制到堆并将引用返回给该对象)的行为。 这允许在需要兼容的引用types的地方传递值types。 它还允许对值types执行虚拟方法调用和引用types的其他function。 拆箱与此操作相反(从盒装对象中取回值types)。

types转换是用于从特定types的variables到另一types的任何types的转换的术语。 这是一个更广泛的概念。

几分钟前, 我回答了一个涉及这个区别的相关问题 。 总而言之,我对由C#转换运算符生成的不同types的IL指令进行了分类:

  1. 拳击( box IL指令)和拆箱( unbox IL指令)
  2. 通过inhertiance层次结构(如C ++中的dynamic_cast<Type> ,使用castclass IL指令进行validation)
  3. 在原始types之间进行转换(如C ++中的static_cast<Type> ,对于原始types之间的不同types的转换,有很多IL指令)
  4. 调用用户定义的转换运算符(在IL级别,它们只是方法调用适当的op_XXX方法)。

拳击是将值types(int,double,float,guid等)转换为引用types(System.Object,System.String等)的术语。 做这个装箱操作在堆上分配内存(垃圾收集器最终需要回收)。 拆箱就是这个过程的反面,取一个引用types并把它变成一个值types。

铸造是采取一种types(比如System.Object),并将其视为另一种types(比如System.String)。

当你用C#打开某些东西的时候,你正在把它转换成另一种types。 不同之处在于它会在创build新的引用types时分配额外的内存

底线:装箱是一种特殊types的转换,将值types转换为引用types,这需要分配一个新的引用types。

装箱/拆箱和types转换是两种不同的操作,但是它们使用相同的语法。

他们只能在谈话的人不知道真正发生的事情时互换使用。

拳击将一个值types存储在堆上的对象,拆箱正在读取对象的值。 您只能将值作为确切types取消装箱。

当您将基本types转换为另一种基本types(如从intlong )或者当您更改引用的types(如从List<int>IEnumerable<int> )时,Casting就是这种情况。

装箱意味着将一个值typesvariables(即一个整数)转换为一个引用types。 拆箱是相反的,使用types铸造。 在.NET世界中,一切都来自于“对象”types。

例如(C#示例):

 int myInt = 0; // original variable (unboxed to begin with) object boxed = myInt; // box it up int myIntUnBoxed = (int)boxed; // and unbox it again using type casting 

从这个出发是types系统的统一,允许价值types被视为参考types。 这篇文章有一个更深入的看拳击/拆箱。