2012-05-23 58 views
19
int a = 2; 

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

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

現在,這裏是我的一些理解的:如果一個結構不能繼承另一個類或結構,爲什麼Int32有一個ToString()方法?

  1. 所有.NET類獲得ToString()方法,它從Object類繼承。
  2. 結構不能從類或其他結構派生。 intInt32類型的結構,它從它實現的接口獲取幾個ToString() [With Parameters]方法。
  3. 還有一個ToString() [未經PARAMS]功能結構Int32

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

結構的Int32覆蓋ValueType.ToString()方法

如果一個結構不能繼承一些類或結構,你能解釋一下這個ToString()方法可用於Int32嗎?

+0

所有類型都以某種方式從Object派生。 int派生自派生自Object的ValueType。你的假設2是錯誤的。 http://ptgmedia.pearsoncmg.com/images/chap13_0321169514/elementLinks/13fig02.gif – 0lukasz0

+0

@ 0lukasz0 [Not * everything * derived from object](http://blogs.msdn.com/b/ericlippert/archive/2009/) 8月6日/不被一切 - 導出 - 從 - object.aspx)。 – vcsjones

+0

「結構Int32重寫ValueType.ToString()方法」回答你自己的問題。 –

回答

30

如果結構不能繼承某些類或結構,

這是不正確的。所有結構(以及內置值類型,如System.Int32,System.Single等)總是隱含地繼承自System.ValueType(其繼而從System.Object繼承)。

但是,您不能創建一個從繼承的其他結構

這在C#語言規範中明確規定,4.1.1:

4.1.1 System.ValueType類型

所有值類型隱式地從類System.ValueType,它繼承繼而從類對象繼承。任何類型都不可能從值類型派生,並且值類型因此被隱式密封(第10.1.1.1.2節)。

然後,更新版本(4.1.3)結構被明確地定義爲一個值類型:

4.1.3結構類型

結構類型爲值類型,它可以聲明常量,字段,方法,屬性,索引器,運算符,實例構造函數,靜態構造函數和嵌套類型。

+0

所以,如果我正在創建一個新的自定義結構,我不能從任何其他類繼承,但現有的結構的繼承自ValueType?你能證實嗎? – robot

+5

@robot *即使您沒有明確聲明它繼承自ValueType(即使您想要,您也無法完成),所有結構體都從ValueType繼承,即使是您創建的結構體。 – vcsjones

+0

感謝您的回答 – robot

1

Int32實現IFormattable,它定義了ToString方法

+2

IFormattable定義了一個參數化的ToString方法,而不是OP詢問的無參數ToString方法。 – phoog

1

自ValueType派生的類型的每一個定義實際上定義了兩種不同類型的東西,在運行時:一個類型堆對象(其從ValueType和導出從Object開始,其中包含嵌入的類型信息)以及一種存儲位置(不包含任何嵌入類型信息,但需要使用它的代碼必須具有其他方法來知道它是什麼)。堆對象類型的實例包含存儲位置類型的字段,嘗試訪問this的代碼將訪問該字段。如果將值類型隱式或顯式強制轉換爲引用類型的存儲位置,系統將創建一個具有適當類型的新堆對象,並將值類型的所有公用和專用字段複製到堆對象內的相應字段。如果堆對象被轉換爲值類型的存儲位置,堆對象中的所有公用和專用字段將被複制到值類型的存儲位置。

如果嘗試在值類型的堆對象上使用任何Object或接口方法,該方法將與其他任何堆對象方法一樣被調用。如果嘗試在值型存儲位置上進行,對於除GetType以外的任何方法,編譯器將生成一個特殊的「約束」操作碼,該操作碼通知運行時存儲位置的類型並指示運行系統調用適用於該類型的方法。由於編譯器將具有可用的存儲位置類型,並且運行時可以使用它來查找適當的方法,因此可以直接在存儲位置調用適當的方法,而無需首先創建新的堆對象。 GetType是一個值得注意的例外;因爲它通過檢查嵌入在對象中的類型信息來工作,所以它只能處理嵌入類型信息的事物。因此,它的參數將在調用之前轉換爲堆對象形式;然後GetType將能夠檢查堆對象的嵌入類型信息。

+0

您是否試圖避免使用術語* boxing *(或其任何變體)? –

+0

@BenVoigt:我不希望在'Int32'上調用'ToString'會涉及拳擊[它可能被定義爲需要拳擊的方式,但我不知道爲什麼會這樣]。提到將對象轉換爲堆對象形式的過程稱爲裝箱過程可能是一件好事,但我不確定如何以及如何最好地說出這一點,而不會分散主要觀點,這就是這樣一個過程調用'Int32.ToString()'時不需要。 – supercat