System.Object类与Structs之间的关系

我知道我的问题似乎很愚蠢,但我很困惑。 如果有人为我澄清这一点,我感激不尽。

我知道结构,例如Int32,是值类型,并在堆栈上实例化,而类是引用类型,并在堆上实例化。 我也知道所有结构都是从System.Object类型派生的,这是一个类。 我想知道超类型System.Object是一个引用类型,而子类型Int32是一个值类型是多么可能? 我应该在哪里了解这是如何工作的?

我知道结构,例如Int32,是值类型,并在堆栈上实例化,而类是引用类型,并在堆上实例化。

你不知道,因为为了被归类为知识 ,信仰必须是真实的 。 尽管很多人都相信,但这种信念当然不是真的。

有时在堆栈上分配值类型。 有时在堆栈上分配引用引用堆上分配的内存。 有时在堆上分配值类型。 (当然,值类型和引用也可以分配堆栈和堆中的寄存器中。)

决定在堆上分配的存储以及在堆栈上分配的内容的因素是存储的已知生存期要求 ,而不是它的类型 。 如果已知变量是短暂的,那么它可以在堆栈上分配; 如果不知道它是短暂的,那么它必须在堆上分配。

我也知道所有结构都是从System.Object类型派生的,这是一个类。 我想知道超类型System.Object是一个引用类型,而子类型Int32是一个值类型是多么可能?

我怀疑你不明白“inheritance”是什么意思,如果这让你感到困惑的话。 当我们说System.Int32(一个值类型)inheritance自System.Object(一个引用类型)时,我们的意思是Object的所有成员也是Int32的成员 。 Object有一个方法“ToString”。 那是Object的成员。 因此Int32也有一个方法“ToString”,因为Int32inheritance自Object。

这就是inheritance的意思。 我怀疑你相信inheritance意味着别的东西,而且无论那个“东西”是什么都会阻止值类型扩展引用类型。 无论你有什么信念,你都认为价值类型不能从引用类型inheritance,这显然是错误的,因为很明显它们就是这样。

我有兴趣了解人们对编程语言的错误认识; 你认为错误的是什么,inheritance关系会阻止值类型从引用类型派生?

您应该阅读并理解所有这些文章:

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

首先,值类型的区别特征不是它们存储的位置,而是它们如何传递给方法。 结构是按值传递的; 这是参数的副本被创建并传递。 方法中对副本的任何更改都不会影响实际参数(除非它们共享相同的引用)引用类型通过引用传递; 这是一个指向实际参数的指针。

是的,结构派生自ValueTypeValueType派生自Object 。 因此,最终结构也来自Object 。 (例如,方法ToString()==Equals()GetHashCode()以及其他一些在Object中定义,因此也可以在struct中使用)

但是,参数传递的语义不是在类本身中定义的; 在Object的定义中没有代码说“我的子类型的任何实例都将通过引用传递”,并且ValueType的定义中没有代码说“我的子类型的任何实例都要按值传递”。 [也许有一个特殊的属性,但不计算]编译器有责任尊重这一点。 (C#编译器中的某些代码会说“生成代码,使得ValueType的后代将按值传递,而其他代码将通过引用传递”)

Eric Lippert的博客是关于C#的许多问题的绝佳资源,您应该阅读@Heinzi提供的链接以进一步澄清。