如果一个结构不能继承另一个类或结构,为什么 Int32 有一个 ToString() 方法

本文关键字:结构 Int32 为什么 有一个 ToString 方法 继承 一个 不能 另一个 如果 | 更新日期: 2023-09-27 18:35:04

int a = 2;
Console.WriteLine(a.ToString()); // displays 2
// definition of ToString() here - public override string ToString();

现在,以下是我的一些理解:

  1. .net 中的所有类都获取一个 ToString() 方法,该方法继承自Object类。
  2. 结构
  3. 不能派生自类或其他结构。 int 是一个类型 Int32 的结构,它从它实现的接口中获取几个ToString() [带参数] 方法。
  4. 在结构Int32中还有一个ToString()[没有参数]函数

据 http://msdn.microsoft.com/en-us/library/system.int32.tostring.aspx,

struct Int32 覆盖 ValueType.ToString() 方法

如果结构不能继承某个类或结构,您能否解释一下这种ToString()方法如何可用于Int32

如果一个结构不能继承另一个类或结构,为什么 Int32 有一个 ToString() 方法

如果结构不能继承某个类或结构,

这不是真的。 所有结构(以及内置的值类型,如System.Int32System.Single等)总是隐式继承自System.ValueType(而又从System.Object继承)。

但是,您不能创建从其他任何内容继承的结构。

这在 C# 语言规范 4.1.1 中有明确说明:

4.1.1 系统值类型

类型

所有值类型都隐式继承自类 System.ValueType,而类 System.ValueType 又从类对象继承。任何类型都不可能从值类型派生,因此值类型是隐式密封的 (§10.1.1.2)。

然后,稍后将 (4.1.3) 结构显式定义为值类型:

4.1.3 结构体类型

结构类型是可以声明常量、字段、方法、属性、索引器、运算符、实例构造函数、静态构造函数和嵌套类型的值类型。

从 ValueType 派生的类型的每个定义实际上在运行时中定义了两种不同类型的事物:一种类型的堆对象(派生自 ValueType,又派生自 Object,并且包含嵌入的类型信息)和一种存储位置类型(不包含任何嵌入的类型信息,而是要求使用它的代码必须具有一些其他方法来知道它是什么)。 堆对象类型的实例包含存储位置类型的字段,尝试访问this的代码将访问该字段。 如果值类型隐式或显式强制转换为引用类型的存储位置,则系统将创建具有适当类型的新堆对象,并将值类型的所有公共和私有字段复制到堆对象中的相应字段。 如果将堆对象强制转换为值类型的存储位置,则堆对象中的所有公共和私有字段都将复制到值类型的存储位置。

如果尝试在值类型的堆对象上使用任何Object或接口方法,则将像任何其他堆对象方法一样调用该方法。 如果尝试在值类型的存储位置上进行,对于除GetType以外的任何方法,编译器将生成一个特殊的"约束"操作码,该操作码通知运行时存储位置的类型,并指示运行时调用适合该类型的方法的地址。 由于编译器将具有可用的存储位置类型,并且运行时可以使用它来查找适当的方法,因此可以直接在存储位置上调用适当的方法,而无需先创建新的堆对象。 GetType是一个值得注意的例外;由于它通过检查嵌入在对象中的类型信息来工作,因此它只能处理嵌入了类型信息的内容。 因此,它的参数将在调用之前转换为堆对象形式; 然后,GetType将能够检查该堆对象的嵌入类型信息。

Int32实现了IFormattable,它定义了ToString方法