You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#身份转换的值表示保留含义及装箱对值类型表示的疑问

C#身份转换中“值的表示”详解及引用类型与装箱的差异

什么是“值的表示”?

这里的**“表示(representation)”是CLR层面的正式概念,指的是数据在内存中的二进制存储结构、存储位置以及底层访问逻辑**。它决定了CLR如何识别、存储和操作一段数据。

引用类型转object:不改变值的表示

引用类型(如string、自定义类、委托等)在CLR中的内存表示本质是指向托管堆中对象实例的指针(32位系统是4字节,64位是8字节)。当你将引用类型转换为object时:

  • 仅改变了编译时的类型标识,让编译器将该引用视为object类型,但内存中存储的指针值完全不变。
  • 以你的示例为例:
    public delegate void PrintString(string value);
    public static void PrintAnything(object value) { Console.WriteLine(value); }
    
    PrintString ps = PrintAnything;
    
    这段代码的委托赋值利用了引用类型的协变特性:string是object的子类,将接受object的方法赋值给接受string的委托时,底层传递的引用没有任何变化——PrintAnything处理的string参数,依然是指向托管堆中string对象的原指针,只是编译时被标记为object类型。
  • 总结:引用类型转object没有修改内存中的二进制数据(指针值),只是调整了类型的“认知标签”,因此是“保留值表示”的身份转换。

值类型装箱:改变值的表示

值类型(如int、struct)默认的内存表示是值本身的二进制数据(比如int就是4字节的数值),通常存储在栈上(或作为引用类型字段存在堆上),没有额外的对象元数据。当值类型装箱时:

  1. CLR会在托管堆上创建一个新的对象实例,该实例包含CLR所需的对象头(类型标识、同步块索引等元数据)。
  2. 将栈上的值类型数据完整复制到堆对象的实例数据区域。
  3. 返回指向这个堆对象的引用。
  • 此时,原来的值类型(栈上的纯数值)和装箱后的对象(堆上带元数据的结构),内存表示完全不同:前者是直接存储值,后者是包含元数据的对象结构,因此装箱操作改变了值的表示。

内容的提问来源于stack exchange,提问作者cookieMonster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:23:22