System.Object类和结构体之间的关系

5

我知道我的问题看起来很蠢,但我很困惑。如果有人能为我澄清一下就好了。

我知道结构体(例如Int32)是值类型,在堆栈中实例化,而类是引用类型,在堆中实例化。我也知道所有的结构体都源自System.Object类型,它是一个类。我想知道这种情况是如何可能的:超类型System.Object是引用类型,子类型Int32是值类型?我应该去哪里查找以了解这是如何工作的呢?


7
相关阅读:堆栈是实现细节 - Heinzi
2
可能是 https://dev59.com/qXI-5IYBdhLWcg3wxbjv 的重复问题。 - daryal
1
http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx - Mike Zboray
2个回答

12
我知道结构体(例如Int32)是值类型,它们在堆栈上实例化,而类是引用类型,它们在堆上实例化。但这个观点并不完全正确,因为有些情况下值类型也会在堆上分配空间,引用类型也可以在堆栈上分配空间。而存储是在堆还是在栈上分配取决于其生命周期的要求,而不是其类型。所有的结构体都派生自System.Object类型,但类型派生关系只表示子类型继承父类型的成员,不涉及到值和引用类型的区别。

我感兴趣了解人们对编程语言存在的错误观念;你认为哪些关于继承关系的错误观念会阻止值类型从引用类型派生?

你应该阅读并理解以下所有文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

http://ericlippert.com/2011/09/19/inheritance-and-representation/

额外的奖励,这篇文章也可能对你有帮助:

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx


5
我不是原帖作者,但我认为继承的常见信念是:如果你创建一个Derived类型的对象,则(概念上)必须创建一个Base类型的对象,然后再添加每个进一步派生类型,直到构造出Derived类型(毕竟,我们在调用链中调用了每个基类构造函数)。因此,要创建一个Int32,你必须创建一个Object类型的对象,从而得到一个引用类型。 - Michael Stum
谢谢你,Eric。我正想着像Michael说的那样,但对我来说有点奇怪。 - Morteza
3
@MichaelStum: 这里的关键词是“概念上”--确实,构建一个int*概念上是首先构建一个对象。但是,在实际操作中,这并不是实际发生的事情,因为系统已经被精心设置,使其不需要发生。 - Eric Lippert

3
首先,值类型的区别特征并不在于它们存储的位置,而是它们传递给方法的方式。结构体是按值传递的;也就是说,会创建一个参数的副本并进行传递。在方法内部对副本所做的任何更改都不会影响实际参数(除非它们共享相同的引用)。引用类型是按引用传递的;也就是说,会传递指向实际参数的指针。
是的,结构体是派生自ValueType的。而ValueType又是派生自Object的。因此,最终结构体也是从Object派生的。(例如,ToString()、==、Equals()、GetHashCode()等方法在Object中定义,因此也可在结构体中使用)
然而,类本身并没有定义参数传递的语义;在Object的定义中没有任何代码指定“我的子类型的任何实例都应该按引用传递”,在ValueType的定义中也没有任何代码指定“我的子类型的任何实例都应该按值传递”。(也许有一些特殊属性,但这并不重要)这是编译器遵守的责任。(在C#编译器中,某个地方有一些代码,指定后代ValueType将按值传递,其他类型将按引用传递)
Eric Lippert的博客是关于C#的许多问题的绝佳资源,您应该阅读@Heinzi提供的链接以获取更多澄清信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接