8

可以从c#中的类派生结构吗?

如果不是,为什么原始数据类型(例如 int)可以从类派生object?由于数据类型 int 基本上是结构类型(值类型)。

这只是规则的例外吗?

4

4 回答 4

9

整数和其他值类型(例如 bool)是对象,因为它允许它们利用继承(即它们可以访问公共.Equals(), .GetType(),.ToString()函数)。

这是 .NET 框架中的设计决策。他们没有为 System.ValueType 下的所有值类型编写单独的函数,而是使用公共代码库。

Microsoft 关于类型的文档

于 2012-12-04T17:14:42.847 回答
6

所有结构都继承System.ValueType,而后者又继承Object

你无法改变这一点。

于 2012-12-04T17:06:22.157 回答
1

当运行时为一个类型分配一个存储位置,或生成操作一个类型的代码时,它会检查该类型是否派生自System.ValueType但不是System.ValueType它自己。除非存储位置满足这些条件,否则它将持有一个堆对象引用,并且任何对其成员(字段、方法、属性等)进行操作的代码都将作用于被引用的对象。否则,存储位置将保存该类型的所有公共和私有字段(将在该类型的所有存储位置中以相同的方式布局),并且对其成员进行操作的任何代码都将在存储位置本身上进行操作。

如果尝试将值类型存储到 classValueType的存储位置,或者不是从 派生的存储位置ValueType,系统将生成该存储位置类型的新堆对象,然后将对该对象的引用存储在适当的存储位置。虽然派生自 的类型的存储位置System.ValueType和访问它们的代码由运行时特殊处理,但继承自的堆对象实例System.ValueType(例如刚刚提到的新创建的实例)只是碰巧派生自的堆对象System.ValueType,并且具有与其他类型基本相同的继承行为,因此可以通过期望处理堆引用的代码传递。

像这样的陈述Object Foo = New System.Drawing.Point(3,4);实际上涉及三种事情:

  1. `System.Drawing.Point(3,4)` 类型的未命名临时存储位置,它保存该类型的私有字段(两个整数),并初始化为 (3,4)。请注意,此存储位置不包含“对象”;它包含两个整数,编译器知道它们代表它的字段。
  2. `System.Drawing.Point` 类型的堆对象。因为这是一个堆对象,它继承自 `System.Object`,所有堆对象也是如此。
  3. `Object` 类型的存储位置,由变量名 `Foo` 表示。

所有这一切的结果是,虽然值类型可以被定义为继承自ValueTypewhich 继承自Object,而其类型继承自的堆对象ValueType确实继承自Object,但值类型的存储位置Object不包含继承自的东西。

于 2012-12-04T18:59:23.437 回答
0

类层次结构如下(简化):

对象 -> 值类型 -> 整数对象 -> 值类型 -> 结构

c# 定义的结构不允许继承。

这是一篇很好的文章,描述了结构在 C# 语言中的作用:

http://msdn.microsoft.com/en-us/library/aa288471(v=vs.71).aspx

于 2012-12-04T17:15:23.397 回答