在 .NET 中,每种类型都继承自 System.Object 吗?

32

这可能是一个非常基础的问题,但我有点困惑。 如果我反射Int32 / Double / 任何值类型代码,我会看到它们是结构体,并且看起来像:

[Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
public struct Double : IComparable, IFormattable, IConvertible, IComparable<double>, IEquatable<double>
{
....
}

那么,为什么我们说.NET中的所有内容都派生自System.Object呢?我觉得我在这里缺少一些关键点。

编辑: 更让我困惑的是,一个值类型(即结构体)如何从一个类(即System.Object)继承。

4个回答

37

Eric Lippert在他的博客文章中已经涵盖了这个问题:Not everything derives from object(这是博客文章的标题;不是这个问题的答案,不要混淆)。

是的,所有的struct都继承自System.ValueType,后者又继承自System.Objectenum继承自你声明的 System.Enum,后者继承自System.ValueType

更新:

本质上,值类型继承自引用类型并没有问题。继承是两个类型之间的“is-a”关系。但是,为了将值类型视为对象实例,必须进行装箱操作。当您将一个值传递给一个期望对象参数的方法时(或者调用在System.Object中实现的实例方法时),会隐式进行此操作。


我刚刚在另一篇文章中链接了该条目... - Brian Rasmussen
枚举和结构体继承自System.ValueType,而System.ValueType又继承自System.Object - Mehrdad Afshari
@Mehrdad,你说枚举和结构体继承自System.ValueType。我在哪里可以看到这个?使用反编译器我看不到。 - P.K
1
PK:您可以使用.NET Reflector和ildasm.exe来查看。在Reflector中,转到mscorlib > System > Int32,Enum,... > Base Types,您将看到System.ValueType。 - Mehrdad Afshari
@Mehrdad:“你在代码中编写的结构体就是一个结构体。”这是什么意思? - P.K
显示剩余5条评论

8

并非所有类型都是如此,但System.Double是这样的。

根据Eric Lippert的帖子:

所有值类型,包括枚举和可空类型,都派生自object

在C#中,结构体是System.ValueType的语法糖,这意味着System.Double派生自System.ValueType。 由于System.ValueType派生自System.Object,因此System.Double也是如此。 您可以使用.Net Framework源代码或使用.Net Reflector查看:


.class public sequential ansi serializable sealed beforefieldinit Double
    extends System.ValueType


更新:

在工具栏上,如果你选择C#,你会看到(这就是你所看到的): alt文本 http://bqqqkg.bay.livefilestore.com/y1pk3EAm_SJtl4dn51HLrhdgHAXCS08-xY9nQUARCpT4WnBQyRHD4RLmIK9zZ4okJXMj7Xopg1EBuY_Od7_oWz7Pw/DoubleCSharp.jpg

如果你改变ComboBox并选择IL,那么你会看到: alt文本 http://bqqqkg.bay.livefilestore.com/y1pRXk-0rDvFjj7b8EqU9-bydzpWjVGJMq8pDbiCr6aALob3j-aC9vvbeBS4vQRedHJ5Dh2CWtYRCywMJ9FGHOaaw/DoubleIL.jpg

请注意,在IL中,Double扩展了System.ValueType。


不仅仅是Double,还有所有基本类型,如int、short、long、decimal等,都是从System.ValueType派生而来的。 - shahkalpesh
1
我知道。我碰巧使用Double作为他的例子。 - Alfred Myers
Double是一个结构体。它如何派生自System.ValueType?此外,我可以看到Double的代码。它只是实现了接口。 - P.K
5
请阅读答案。如果你查看IL码而不是元数据或反编译为C#代码,就会发现Double继承自ValueType。根据C#规范:结构体是值类型($11.3.1)所有结构体类型都隐式地继承自类System.ValueType($11.3.2)。 - Alfred Myers

4

3
就您的问题而言,结构体从ValueType 隐式继承,后者又派生自 object。
除此之外,Eric Lippert 上面发布的链接是您想要阅读的。

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