c# - 如何将 "int"分配给对象?

标签 c# .net types

我们如何能够将整数分配给 .NET 中的对象?

引用类型派生自 System.Object,值类型派生自 System.ValueType。

那么,这怎么可能呢?

最佳答案

术语“装箱”非常不透明,但使用调试器很容易将实际发生的事情可视化。编写一个像这样的小控制台模式应用程序:

using System;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            int value = 42;
            object obj = value;
        }  // <== Breakpoint here
    }
}

在指定位置设置断点,然后按 F5。当断点命中时,使用 Debug + Windows + Memory + Memory 1. 在地址框中,键入“obj”。您将获得对象内存内容的十六进制转储。右键单击窗口并选择“4 字节整数”,这是本例中可视化对象的最佳方式。你会看到类似这样的东西:

0x01CBF6BC  6e1a2d34 0000002a

这里有趣的部分是 0x01CBF6BC,这是垃圾收集堆上对象的地址。下一个十六进制数 6e1a2d34 就是所谓的“类型句柄”,也称为“方法表指针”。一个识别对象类型的“cookie”。 System.Int32 在这种情况下。非常重要,稍后当对象被取消装箱返回 Int32 时将使用它来验证装箱的值实际上是一个整数。

您看到的下一个值 0000002a 是装箱对象的值。你可以在程序员模式下使用 Windows 计算器将其转换回十进制,即 42。

对此进行试验,使用不同的值和不同的类型来查看它如何影响装箱的对象。您可以修改十六进制并查看它对调试器显示的 obj 值有何影响。

我给你的十六进制转储是一个 4 字节的装箱值,装箱一个 double 将占用 8 个字节。装箱结构将占用更多字节。还有一部分你看不到的对象头,即所谓的同步块(synchronized block),位于地址 - 4。尝试 lock 语句以查看其变化。

关于c# - 如何将 "int"分配给对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5383074/

相关文章:

c - 用于检查超出的任何数据类型的最大值的 API

python - 嵌入式 python : extern PyRun_SimpleString, 预期标识符

c++ - 读取存储在 double 中的 8 字节字段的 4 个字节

c# - 如何在 C# 中为位图设置宽度和高度?

.net - 引用类型中定义的值类型存储在哪里(堆或堆栈)?

.net - OutputCache 为长期陈旧数据提供服务

c# - 如何使用 .NET Framework 获取所有事件的 TCP 连接(无非托管 PE 导入!)?

C# 在一个端口上与多个设备进行串行通信

c# - 为什么我们不能将常量变量定义为static?

c# - Protobuf-net 对象引用反序列化使用字典 : A reference-tracked object changed reference during deserialization