【问题标题】:How is an "int" assigned to an object?如何将“int”分配给对象?
【发布时间】:2011-07-19 23:28:05
【问题描述】:

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

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

那么,这怎么可能呢?

【问题讨论】:

    标签: c# .net types


    【解决方案1】:

    试试这个方法:

    object ob;
    int i=10;
    ob=i;//(boxing)
    int b;
    b=(int)ob;//(unboxing)
    

    【讨论】:

      【解决方案2】:

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

      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-byte Integer”,这是在这种情况下可视化对象的最佳方式。你会看到类似这样的东西:

      0x01CBF6BC  6e1a2d34 0000002a
      

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

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

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

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

      【讨论】:

        【解决方案3】:

        .NET 中的 int 具有底层 Integer 类型对象和隐式转换。

        【讨论】:

        • 我认为您将 .NET 与 Java 混淆了。并且没有任何隐式转换;它仍然是一个 int,伪装成一个对象。
        • 哦,是的,我做到了。这就是我在发帖前没有花时间思考的结果。
        • @BoltClock 实际上,由于奇怪的情况,pwny 是正确的。 .net 中的 int 类型(和其他数字类型)是一种“神奇”类型:单独的 int 值只有 4 个字节,这意味着它不能具有 RTTI。只有当您尝试将其用作对象时(例如装箱时),它才会放入 System.Integer 实例中,该实例只是一个包装器。如果你通过 Reflector 查看System.Integer 类,你会发现它的唯一成员是int m_value。所以一个隐式转换正在进行,唯一的事情是它发生在比预期更低的级别。
        • @BoltClock 或者至少,当我问为什么System.Integer 包含intstackoverflow.com/questions/3375165/…
        【解决方案4】:

        【讨论】:

          【解决方案5】:

          您应该阅读 c# 中的 boxing and unboxing,它应该会告诉您他们如何/为什么。

          此链接有很好的解释,并解释了您所询问的参考与值类型问题:

          http://www.dijksterhuis.org/exploring-boxing/

          装箱就像简单地将一个基本类型放入包装器中(使其成为一个完全成熟的对象),然后拆箱取出该包装的对象并将其转换回一个更简单的类型。要进行装箱托管内存需要在堆上分配,需要更新引用,并且必须复制值类型的内容。

          【讨论】:

            【解决方案6】:

            System.ValueType 也是从 System.Object 派生的,这就是为什么:

            在此处查看继承层次结构:

            http://msdn.microsoft.com/en-us/library/system.valuetype.aspx

            【讨论】:

              【解决方案7】:

              Boxing and Unboxing:

              装箱是将值类型转换为类型对象或此值类型实现的任何接口类型的过程。当 CLR 将值类型装箱时,它会将值包装在 System.Object 中并将其存储在托管堆中。拆箱从对象中提取值类型。

              【讨论】:

                【解决方案8】:

                【讨论】:

                  【解决方案9】:

                  你是boxing对象中的整数。

                  也就是说,创建了一个包装(或)整数的对象。有点像在现实生活中把东西放在盒子里。

                  【讨论】:

                  • 拳击是一种物理现象。这实际上是如何发生的(整数不属于 System.Object)?
                  • dtb 在同一文档中的引用很好地总结了这一点。
                  猜你喜欢
                  • 1970-01-01
                  • 2013-10-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-10-10
                  • 2011-09-03
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多