拳击是指将值类型分配给对象类型。将引用类型分配给对象时是否相同?
当分配了一个类型(不是对象)时,会发生什么?那拳击呢?
int num=5;
object obj = num; //boxing
//////////////////////
MyClass my = new MyClass();
object obj = my; //what is name this convert (whethere is boxing?)
答案 0 :(得分:20)
拳击是指将值类型分配给对象类型。
关闭。当值类型的值转换到引用类型时,会发生“装箱”。
将引用类型的值赋给对象类型的变量时是否相同?
没有。当值类型的值转换为引用类型时,就会发生拳击。将引用类型的值转换为对象不是装箱转换,它是引用转换。
当引用类型的值(不是对象)被赋给对象类型的变量时,会发生什么?
引用类型的值是引用。将引用分配给object类型的变量时,将在与该变量关联的存储位置中创建引用的副本。
那是拳击吗?
没有。当值类型的值被转换为到引用类型时,就会发生拳击。将引用类型的值转换为对象不是装箱转换,它是引用转换。
答案 1 :(得分:11)
我认为你的意思是
string s = "hello";
object x = s; // no boxing, just implict conversion to base-type.
这是有效的,因为System.String
与所有其他类一样,来自System.Object
:
public sealed class String : Object { ... }
答案 2 :(得分:3)
Boxing正在堆栈上创建一个对象引用,它引用类型的值,例如: int,在堆上。但是当一个引用类型(女巫不是对象)分配给对象时,它不是拳击。
答案 3 :(得分:2)
Eric的回答对应于CLI(公共语言基础结构)标准ECMA-335,分区I(架构),第5章(术语和定义),它将装箱定义为:“具有某种值类型的值的转换,对于新分配的引用类型System.Object。“,并取消装箱为:”将类型为System.Object的值(其运行时类型为值类型)转换为值类型实例。
CIL(通用中间语言)的box和unbox指令的行为与此类似,这也是在C#或VB.NET上下文中提到装箱/拆箱时通常隐含的含义。
但是,术语装箱和拆箱有时会用于更广泛/实用的意义上。例如,F#box和unbox运算符可以对System.Object进行值类型和引用类型的转换:
> let o = box "Hello World";;
val o : obj = "Hello World"
> let s:string = unbox o;;
val s : string = "Hello World"
答案 4 :(得分:0)
将提供的代码编译成可运行的可执行文件并对其进行反汇编,会显示第一个分配(obj
)的显式框指令,该指令不存在于第二个分配(obj2
)中:
<强>来源
namespace BoxingAndTypeConversion
{
class Program
{
public class MyClass { }
static void Main(string[] args)
{
int num = 5;
object obj = num; //boxing
//////////////////////
MyClass my = new MyClass();
object obj2 = my; //what is name this convert (whethere is boxing?)
}
}
}
<强> CIL 强>
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 1
.locals init ([0] int32 num,
[1] object obj,
[2] class BoxingAndTypeConversion.Program/MyClass my,
[3] object obj2)
IL_0000: nop
IL_0001: ldc.i4.5
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: stloc.1
IL_000a: newobj instance void BoxingAndTypeConversion.Program/MyClass::.ctor()
IL_000f: stloc.2
IL_0010: ldloc.2
IL_0011: stloc.3
IL_0012: ret
} // end of method Program::Main