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

67 .net boxing unboxing casting

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

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

jas*_*son 44

拳击是指转换不可为空值类型的成引用类型或值类型,它实现了一些接口的转换(说intIComparable<int>).此外,底层值类型到可空类型的转换也是装箱转换.(警告:关于这个主题的大多数讨论将忽略后两种类型的转换.)

例如,

int i = 5;
object o = i;
Run Code Online (Sandbox Code Playgroud)

转换i为类型的实例object.

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

例如,

object o = (int)5;
int i = (int)o;
Run Code Online (Sandbox Code Playgroud)

将装箱的整数转换o为类型的实例int.

类型转换是表达式到给定类型的显式转换.从而

(type) expression
Run Code Online (Sandbox Code Playgroud)

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

  • 为清楚起见,当Jason说"将底层值类型转换为__nullable类型___也是一个拳击转换"时,他所谓的"可空类型"是一个引用类型,可以设置为null - 因此他使用了术语"可空".他的意思不是"Nullable <T>"类型.将值类型转换为`Nullable <T>`(又名`T?`)不是装箱/拆箱的示例,因为没有创建引用类型.例如`int?x = 5`是类型转换的示例,而不是拳击. (13认同)
  • 关于这些事情有非常标准的语言.请参阅C#语言规范,ECMA#334. (10认同)

Meh*_*ari 27

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

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

几分钟前,我回答了一个涵盖这种差异的相关问题.总而言之,我对C#cast运算符生成的不同类型的IL指令进行了分类:

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

  • 这对我没有多大帮助.我想我会在互联网上做一些研究,找到比较的具体定义. (3认同)

Jud*_*ngo 19

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

转换是一种类型(比如System.Object)并将其视为另一种类型(比如System.String).

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

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

  • 不完全正确.首先,它不一定是System.Object,但实际上是*任何引用类型*.例如,`IComparable <int> i = 5`也导致拳击.其次,`boxing`不是唯一需要内存分配的**演员.用户定义的演员也可以自由选择.第三,正如Jason所指出的,堆是实现细节.重要的是*通过引用类型语义*处理值类型而不是它被分配的位置. (5认同)
  • 有时我认为程序员过于迂腐。这是其中之一。 (3认同)
  • 堆是一个实现细节. (2认同)
  • 当海报简单地询问铸造和拳击之间的区别时,我们是否真的需要进入关于堆作为实现细节的辩论?我的回答是正确的 - CLR在堆上分配内存来做拳击.你正确地指出了堆是一个实现细节,尽管很迂腐.我可以反驳说,"但这是当前的实施,一个值得注意的实施,在可预见的未来不太可能改变." ---诚实 - 我们正在用这种迂腐的戏弄来愚蠢. (2认同)

Guf*_*ffa 6

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

仅当谈论它的人不知道到底发生了什么时,它们才可以互换使用......

装箱是将值类型作为对象存储在堆上,而拆箱则是从对象中读取值。您只能将值拆箱,因为它是精确类型。

强制转换是指将一种基本类型转换为另一种基本类型(例如从 anint到 a long),或者更改引用的类型(例如从List<int>IEnumerable<int>)。