装箱/拆箱和铸造有什么区别?

时间:2009-07-06 02:17:21

标签: .net casting boxing unboxing

装箱/拆箱和类型转换有什么区别?

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

5 个答案:

答案 0 :(得分:41)

Boxing是指将非可空值类型转换为引用类型,或将值类型转换为它实现的某个接口(比如intIComparable<int>)。此外,底层值类型到可空类型的转换也是装箱转换。 (警告:关于这个主题的大多数讨论将忽略后两种类型的转换。)

例如,

int i = 5;
object o = i;

i转换为object类型的实例。

取消装箱是指从objectValueType的实例到非可空值类型的显式转换,即将接口类型转换为非可空值类型(例如, IComparable<int>int)。此外,可空类型到底层类型的转换也是拆箱转换。 (警告:大多数关于此主题的讨论将忽略后两种类型的转换。)

例如,

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

o中装箱的整数转换为int类型的实例。

类型转换是表达式到给定类型的显式转换。因此

(type) expression

expression显式转换为type类型的对象。

答案 1 :(得分:25)

装箱和拆箱是类型转换的子集。 Boxing是将值类型视为引用类型的行为(实际上,它涉及将该值类型的内容(从堆栈)复制到堆并返回对该对象的引用)。这允许在期望兼容引用类型的任何地方传递值类型。它还允许对值类型执行虚方法调用和引用类型的其他功能。取消装箱与此操作相反(从盒装对象中取回值类型)。

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

几分钟前I answered a related question that covers this difference。总而言之,我对C#cast运算符生成的不同类型的IL指令进行了分类:

  1. 拳击(box IL指令)和拆箱(unbox IL指令)
  2. 强制转换inhertiance层次结构(如C ++中的dynamic_cast<Type>,使用castclass IL指令进行验证)
  3. 在原始类型之间进行转换(如C ++中的static_cast<Type>,对于基本类型之间的不同类型的转换,有大量的IL指令)
  4. 调用用户定义的转换运算符(在IL级别,它们只是对相应op_XXX方法的方法调用)。

答案 2 :(得分:17)

Boxing是将值类型(int,double,float,Guid等)转换为引用类型(System.Object,System.String等)的术语。执行此装箱操作会在堆上分配内存(垃圾收集器最终需要回收)。拆箱与此过程相反,采用参考类型并将其转换为值类型。

Casting正在使用一个类型(例如,System.Object)并将其视为另一种类型(例如,System.String)。

当您在C#中打包时,您将其转换为其他类型。 不同之处在于,它会在创建新的引用类型时分配额外的内存

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

答案 3 :(得分:4)

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

当谈论它的人不知道究竟发生了什么时,它们只能互换使用......

Boxing将值类型存储为堆上的对象,而取消装箱正在从对象中读取值。您只能将值拆分为确切类型。

转换是指将基本类型转换为其他基本类型(例如从int转换为long),或者更改引用类型时(例如来自List<int>)到IEnumerable<int>)。

答案 4 :(得分:3)

拳击意味着将值类型变量(即整数)转换为引用类型。使用类型转换,拆箱与此相反。在.NET世界中,一切都源于“对象”类型。

例如(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

从中获取的是类型系统的统一,允许将值类型视为引用类型。 This article对拳击/拆箱有更深入的了解。