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

时间:2012-05-23 20:13:37

标签: c# .net inheritance struct

int a = 2;

Console.WriteLine(a.ToString()); // displays 2

// definition of ToString() here - public override string ToString();

现在,我的一些理解是:

  1. .net中的所有类都获得ToString()方法,该方法继承自Object类。
  2. 无法从Class或其他结构派生结构。 intInt32类型的结构,它从它实现的接口中获取了几个ToString() [With Parameters]方法。
  3. 结构ToString()
  4. 中还有Int32 [无参数]函数

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

      

    struct Int32重写ValueType.ToString()方法

    如果某个结构不能继承某个类或结构,请解释这个ToString()方法如何用于Int32

3 个答案:

答案 0 :(得分:32)

  

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

事实并非如此。所有结构(以及内置值类型,如System.Int32System.Single等)始终隐式继承自System.ValueType(反过来,继承自System.Object)。

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

这在C#语言规范4.1.1中清楚地说明:

  

4.1.1 System.ValueType类型

     

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

然后,稍后(4.1.3)将struct明确定义为值类型:

  

4.1.3结构类型

     

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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