【发布时间】:2017-08-28 20:20:11
【问题描述】:
我对 C# 中的装箱和拆箱有一点疑问。
int i=1;
System.Int32 j = i;
以上代码可以称为拳击吗?
【问题讨论】:
-
谢谢你,kalale aata。
标签: c# value-type boxing
我对 C# 中的装箱和拆箱有一点疑问。
int i=1;
System.Int32 j = i;
以上代码可以称为拳击吗?
【问题讨论】:
标签: c# value-type boxing
不,那根本不是拳击。 int 只是 System.Int32 的别名。该代码相当于:
int i = 1;
int j = i;
要发生装箱,必须转换为引用类型,例如
int i = 1;
object j = i;
或者:
int i = 1;
IComparable j = i;
【讨论】:
只是为了稍微扩展乔恩的答案,当您调用基类的非覆盖或非虚拟方法时,也会发生装箱,例如
i.GetType(); //boxing occur here
或将int 传递给需要引用类型的方法
void Foo(object obj) {}
Foo(i); //boxing, no overload takes an int
在第一个例子IL你可以清楚地看到box指令
int i = 5;
i.GetType();
IL_0000: ldc.i4.5
IL_0001: stloc.0 // i
IL_0002: ldloc.0 // i
IL_0003: box System.Int32 //<---- boxing
IL_0008: call System.Object.GetType
如果你的值类型中没有覆盖虚方法,它们在调用时也会被装箱
enum MyEnum {}
var e = new MyEnum();
e.ToString(); //box will occur here, see IL for details
IL_0000: ldc.i4.0
IL_0001: stloc.0 // e
IL_0002: ldloc.0 // e
IL_0003: box UserQuery.MyEnum
IL_0008: callvirt System.Object.ToString
与结构相同的情况,除了它们将使用callvirt 操作码,如果需要,它将对结构进行装箱,
【讨论】:
没有。 int 是一个值类型。
将值类型分配给对象时会发生装箱。
【讨论】:
这不是拳击。
int 是System.Int32 的别名。所以你的代码相当于;
int i = 1;
int j = i;
对于装箱,应该有到对象或接口的转换。喜欢;
int i = 1;
object j = i;
类类型的值可以转换为类型对象或 类实现的接口类型,只需处理 在编译时引用为另一种类型。同样,类型的值 对象或接口类型的值可以转换回 类类型而不更改引用(但当然是运行时 在这种情况下需要进行类型检查)。
【讨论】: