System.Object如何在内部存储"对象"?

ric*_*ard 2 .net store object

我正在阅读有关拳击的内容,书中说"拳击可以正式定义为通过将变量存储在aSystem.Object中而将值类型显式转换为相应的引用类型的过程." (重点补充)

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

object objShort = 5;
Run Code Online (Sandbox Code Playgroud)

但是也

object someOtherObj = someReallyComplicatedObject;
Run Code Online (Sandbox Code Playgroud)

我一直在寻找,包括这里(MSDN System.Object),我没有看到任何描述System.Object实例如何实际存储其数据的地方.

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

(乔恩,请原谅我,如果这也出现在你的书中.我订购了它,它正在路上!)

Jon*_*eet 8

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

我还想纠正"存储变量"部分 - boxing将存储在一个对象中.该值可能是变量的值,也可能是方法调用的结果,或者其他任何值.

当然,对于参考类型,根本不需要拳击.你真的需要区分一个引用和一个对象 - 一旦你在脑海中清楚地了解了这两个,大多数其他事情都很容易.然后记住,变量的值永远不是一个对象 - 它只是一个值类型值或引用(或指针:)

(哦,这在C#深度有所涉及,但不是很详细.你可能会对Eric Lippert的帖子"关于价值类型的真相"感兴趣.)


Eri*_*ert 6

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

sealed class Box<T> : System.ValueType where T : struct
{
    private T value;
    public Box(T t) 
    {
        this.value = t;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一堆其他狡猾的东西:

  • 从显式转换操作符Box<T>T.
  • 从隐式转换操作符TBox<T>简单地调用构造函数.
  • 代理this.value的ToString,GetHashcode和GetType的实现.
  • 等等

从概念上讲,从int到object的装箱转换只是将隐式转换运算符调用intBox<int>.

当然,实际上没有这样的类型Box<T>,如果有的话,它必须充满古怪的东西; 你不能正常覆盖GetType,你不能正常地在一个类中扩展ValueType,它的可行类型的行为很奇怪,依此类推.所有这些细节都是CLR的实现细节,但它有助于想象CLR只是创建一个非常特殊类型的实例来完成装箱和拆箱的工作.