在C#中,装箱(boxing)是把值类型转换为System.Object类型,或者转换为由值类型实现的接口类型。拆箱(unboxing)是相反的转换过程。
例如,以下结构类型:
struct MyStruct
{
public int Val;
}
注:struct 结构体是值类型。
可以把这种类型的结构放在object类型的变量中,对其装箱:
MyStruct valType1 = new MyStruct();
valType1.Val = 1;
object refType = valType1;
其中创建了一个类型为MyStruct的新变量valType1,并把一个值"1"赋予这个结构的Val成员,然后把它装箱在object类型的变量refType中。
以这种方式装箱变量而创建的对象,会包含值类型变量的一个副本的引用,而不包含源值类型变量的引用。要进行验证,可以修改源结构的内容,把对象中包含的结构拆箱到新变量中,检查其内容:
valType1.Val = 2;
MyStruct valType2 = (MyStruct)refType;
WriteLine($"valType2.Val = {valType2.Val}");
执行这段代码将得到如下输出结果:
valType2.Val = 1
但在把一个引用类型赋予对象时,将执行不同的操作。把MyStruct改为一个类(不考虑这个类名不合适的情况),即可看到这种情形:
class
MyStruct
{
public int Val;
}
如果不修改上面的客户代码(再次忽略名称有误的变量),就会得到如下输出结果:
valType2.Val = 2
也可以把值类型装箱到接口类型中,只要它们实现这个接口即可。例如,假定MyStruct类型实现IMyInterface接口,如下所示:
interface IMyInterface {}
struct MyStruct : IMyInterface
{
public int Val;
}
接着把结构装箱到一个IMyInterface类型中,如下所示:
MyStruct valType1 = new MyStruct();
IMyInterface refType = valType1;
然后使用一般的数据类型转换语法对其拆箱:
MyStruct ValType2 = (MyStruct)refType;
从这些示例中可以看出,装箱是在没有用户干涉的情况下进行的(即不需要编写任何代码),但拆箱一个值需要进行显式转换,即需要进行数据类型转换(装箱是隐式的,所以不需要进行数据类型转换)。
您可能想知道为什么要这么做。装箱非常有用,有两个非常重要的原因。首先,它允许在项的类型是object的集合(如ArrayList)中使用值类型。其次,有一个内部机制允许在值类型(例如int和结构)上调用object方法。
最后需要注意的是,在访问值类型内容前,必须进行拆箱。
知乎: @张赐荣
赐荣博客: www.prc.cx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!