22
int a = 2;

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

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

现在,这是我的一些理解:

  1. .net 中的所有类都有一个方法,该方法是从该类ToString()继承的。Object
  2. 结构不能从类或其他结构派生。int是一个 type 的结构,它从它实现的接口中Int32获取几个[With Parameters] 方法。ToString()
  3. struct中还有一个ToString()[without params] 函数Int32

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

struct Int32 覆盖 ValueType.ToString() 方法

如果一个结构不能继承某个类或结构,你能解释一下这个ToString()方法是如何可用的Int32吗?

4

3 回答 3

34

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

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

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

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

4.1.1 System.ValueType 类型

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

然后,稍后(4.1.3) struct 被显式定义为值类型:

4.1.3 结构类型

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

于 2012-05-23T20:16:06.080 回答
1

Int32implements IFormattable,它定义了ToString方法

于 2012-05-23T20:17:23.467 回答
1

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

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

于 2012-10-08T15:53:34.420 回答