2012-06-10 49 views
1

我對.NET中的繼承感到困惑,這就是爲什麼。結構是否可以從.NET中的類繼承?

我以前的理解是一個結構不能從.NET類繼承,因此,例如,以下不會編譯:

struct MyStruct : MyClass 
{ 

} 

但是今天我讀了整數(等價值類型)是結構體而不是對象,它們繼承自ValueType類。 ValueType類繼承自System.Object,其目的是覆蓋System.Object中的某些方法,以使這些方法適用於值類型。

那麼有什麼交易?一個結構是否可以從.NET中的類繼承,它是否可以或只能在某些情況下才能使用?

由於

+2

重複? http://stackoverflow.com/questions/10727151/if-a-struct-cannot-inherit-another-class-or-struct-why-does-int32-have-a-tostri – Jake1164

+0

@ Jake1164是的,這傢伙是基本上問我同樣的問題!我的錯! – JMK

回答

3

.NET的膽內,對於含有某些成員結構的定義是一樣的,其對於那些相同的字段和成員的類的定義,並且其從System.ValueType繼承。請注意,編譯器將不允許聲明繼承ValueTypeclass,但是當聲明struct時,編譯器「幕後」聲明瞭一個類。

什麼使.n​​et中的值類型特殊是運行時分配存儲位置(變量,字段,參數等)的方式當聲明不從ValueType繼承的類型的存儲位置時,運行時將分配堆對象引用的空間。相比之下,當聲明從ValueType繼承的類型的存儲位置時,運行時將爲該類型的所有公用和專用字段分配空間。對於像int這樣的類型,系統在正常類型系統之外分配一個特殊基本類型的專用字段。

請注意,值類型的存儲位置並不真正包含該類型的實例;而不是該類型的一個實例,而則包含該類型的所有字段。像struct1 = struct2這樣的語句不會用實例struct2替代值類型實例struct1。相反,它會將struct2中的所有字段複製到struct1的相應字段中。同樣,如果將值類型的存儲位置作爲方法傳遞給過程而不使用關鍵字ref,則傳遞的內容不是結構實例本身,而是其字段內容。

如果有必要的值型存儲位置複製到不從ValueType(例如ObjectIComparable),系統將創建值類型的新堆對象實例派生類型的一個,複製所有字段從值類型添加到新實例,並將對該新實例的引用存儲在目標存儲位置中。這個過程被稱爲「拳擊」。大多數編譯器會隱式地執行此操作,因此試圖表現得好像值類型的存儲位置持有來自ValueType的對象。不過,需要注意的是,這是一種幻覺。如果類型XY派生,一個有一個名爲xxX和一個名爲yyY,和一個執行xx = yy,這樣的說法應該引起xxyy指同一個對象實例。如果xxyy不是從ValueType派生的類型,即使yy包含從ValueType派生的某個事件的實例,也會發生這種情況。但是,如果xx和/或yy來自ValueType,則不會發生。在這種情況下,系統會將字段從一個實例複製到另一個實例(可能是新實例)。