Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net System.Object如何存储;“对象”;内部?_.net_Object_Store - Fatal编程技术网

.net System.Object如何存储;“对象”;内部?

.net System.Object如何存储;“对象”;内部?,.net,object,store,.net,Object,Store,我读过关于装箱的书,书中说“装箱可以被正式定义为通过将变量存储在System.Object中,将值类型显式转换为相应的引用类型的过程”(重点添加) 我的问题不是关于装箱,但这让我思考——System.Object实例如何以及在何处存储分配给它的值/变量/对象。所以我想知道的不仅仅是 object objShort = 5; 而且 object someOtherObj = someReallyComplicatedObject; 我一直在四处寻找,包括,但我没有看到任何地方描述System.

我读过关于装箱的书,书中说“装箱可以被正式定义为通过将变量存储在
System.Object
中,将值类型显式转换为相应的引用类型的过程”(重点添加)

我的问题不是关于装箱,但这让我思考——System.Object实例如何以及在何处存储分配给它的值/变量/对象。所以我想知道的不仅仅是

object objShort = 5;
而且

object someOtherObj = someReallyComplicatedObject;
我一直在四处寻找,包括,但我没有看到任何地方描述System.Object实例如何实际存储其数据

对象只是简单地存储一个指向分配给它的对象的指针,还是在装箱的情况下,在堆栈上的值类型上存储一个指针


(乔恩,如果这也在你的书里的话,请原谅我。我已经订购了,而且已经在路上了!)

对拳击的描述是不准确的。创建的对象不仅仅是裸
系统的一个实例;每个值类型实际上都有自己的“隐藏”对应引用类型,它只是从
ValueType
派生的一个类,实现了与值类型相同的接口,并具有值类型类型的字段。这肯定是我的想法,至少是CLI规范对它的大致描述
System.Object
本身没有任何存储空间

我还想更正“存储变量”部分-装箱将值存储在对象中。该值可能是变量的值,也可能是方法调用的结果,或者其他任何内容

当然,对于引用类型,根本不需要装箱。不过,你真的需要区分引用和对象——一旦你把这两个概念都想清楚了,大多数其他事情都很容易理解。然后请记住,变量的值永远不是对象-它只是值类型值或引用(或指针:)


(哦,这在C#中有点深入,但不是很详细。不过你可能对Eric Lippert的帖子感兴趣。)

CLR中引用类型的对象(包括C#)与一些元数据一起存储,这些元数据描述了对象的类型、锁的状态和垃圾收集信息等。,以及对象存储的实际数据


当(值类型的)值被装箱时,将为该值类型创建为引用类型创建的相同类型的结构。它是在用于引用类型对象的同一托管堆中创建的,并且受相同的垃圾收集的约束。(因此它不是对堆栈上某个值的引用。)

想象一下,有一种通用引用类型如下所示:

sealed class Box<T> : System.ValueType where T : struct
{
    private T value;
    public Box(T t) 
    {
        this.value = t;
    }
}
密封类框:System.ValueType其中T:struct
{
私人T值;
公用信箱(T)
{
该值=t;
}
}
再加上一堆其他不可靠的东西:

  • Box
    T
    的显式转换运算符
  • T
    Box
    的隐式转换运算符,它只调用构造函数
  • ToString、GetHashcode和GetType的实现将该代理转换为this.value
  • 等等
从概念上讲,从int到object的装箱转换只是从
int
Box
调用隐式转换操作符


当然,在现实中没有像盒子这样的类型,如果有的话,它肯定会充满古怪的东西;不允许您正常地重写GetType,不允许您正常地在类中扩展ValueType,它对可空类型的行为很奇怪,等等。所有这些细节都是CLR的实现细节,但想象一下CLR只是创建了一个非常特殊的类型的实例,该类型执行装箱和取消装箱的工作。

对于引用类型,没有额外的对象;您只有完全相同的引用,但本地编译器只知道它是对象。这里的所有内容都只与值typesAh相关,因此
someOtherObj
只是对内存中相同对象的另一个引用。它只是和编译器的“类型”不同?啊哈。因此,基本上不用显式地创建自己的对象包装器类来将其存储在引用类型中,而是为您完成这项工作。对吗?这是在什么级别完成的,即CIL,还是在由CIL组装的字节码中完成的?@Richard:它是由CLR本身通过box指令完成的。