結構和類別 (Visual Basic)
Visual Basic 統一了結構和類別的語法,因此這兩種實體都支援大部分相同的功能。 不過,結構與類別之間也有重要的差異。
類別的優點是它屬於參考類型 — 傳遞一個參考比傳遞一個包含其所有資料的結構變數更有效率。 另一方面,結構不需要在全域堆積上配置記憶體。
因為您無法從結構繼承,所以結構應該只用於不需要擴充的物件。 當您想要建立的物件具有小的實例大小時,請使用結構,並考慮類別與結構之間的效能特性。
相似之處
結構與類別在下列方面類似:
兩者都是容器 類型,這表示它們都包含其他類型做為成員。
兩者都有一些成員,其中可包含建構函式、方法、屬性、欄位、常數、列舉、事件和事件處理常式。
兩者的成員可以具有個別的存取層級。 例如,一個成員可以宣告為
Public
,而另一個成員可以宣告為Private
。兩者都可以實作介面。
兩者都可以具有共用的建構函式 (含或不含參數)。
兩者都可以公開預設屬性 (前提是該屬性至少要採用一個參數)。
兩者都可以宣告和引發事件,而且兩者都可以宣告委派。
差異
結構和類別在下列的特定情況下有所不同:
結構是值類型,而類別是參考類型。 一個結構類型的變數包含該結構的資料,而不像類別類型一樣包含對資料的參考。
結構使用堆疊配置,而類別使用堆積配置。
所有的結構元素預設都是
Public
;類別變數和常數預設是Private
,而其他的類別成員預設是Public
。 類別成員的這個行為提供了與 Visual Basic 6.0 系統預設值的相容性。結構必須至少有一個非共用的變數,或非共用且非自訂的事件元素;而類別可以完全空白。
結構元素不能宣告為
Protected
,而類別成員可以。結構程序只有在它是一個 Shared
Sub
程序,而且只能透過 AddHandler 陳述式時才能處理事件;而任何的類別程序都可以使用 Handles 關鍵字或AddHandler
陳述式來處理事件。 如需詳細資訊,請參閱事件。結構變數宣告無法指定陣列的初始設定式或初始大小;而類別變數宣告可以。
結構可以隱含地繼承自 System.ValueType 類別,但無法繼承自任何其他類型;而類別可以繼承自 System.ValueType 以外的任一個類別或多個類別。
結構是不可繼承的;而類別是可繼承的。
結構永遠不會被終止,因此 Common Language Runtime (CLR) 永遠不會對任何的結構呼叫 Finalize 方法;類別會在記憶體回收行程 (GC) 偵測到沒有任何作用中的參考剩餘時被它終止 (GC 會對類別呼叫 Finalize)。
結構不需要建構函式;而類別需要。
結構只有在採用參數時才能有 nonshared 建構函式;而類別可以含或不含參數來擁有它們。
每一個結構都有一個不含參數的隱含 public 建構函式。 這個建構函式會將所有結構的資料元素初始化為其預設值。 您無法重新定義此行為。
實例和變數
因為結構是值類型,所以每一個結構變數都會永久繫結到一個個別的結構實例。 但類別是參考類型,而物件變數可以在不同時間參考各種類別實例。 這項區別會在下列方面影響您使用結構和類別的方式:
初始化。 結構變數會隱含地使用結構的無參數建構函式來包含元素的初始化。 因此,
Dim s As struct1
相當於Dim s As struct1 = New struct1()
。指派變數。 當您將一個結構變數指派給另一個結構變數,或將結構實例傳遞給程序引數時,所有變數元素的目前值都會被複製到新的結構。 當您將一個物件變數指派給另一個物件變數,或將物件變數傳遞給程序時,只會複製參考指標。
指派 Nothing。 您可以將 Nothing 值指派給結構變數,但實例會繼續與該變數相關聯。 您仍然可以呼叫其方法並存取其資料元素 (儘管變數元素已被該指派重新初始化也一樣)。
相反地,如果您將物件變數設為
Nothing
,則會將其與任何類別實例解除關聯,您必須等到將另一個實例指派給該變數之後才能透過該變數來存取任何的成員。多個實例。 一個物件變數可以擁有在不同時間指派給它的不同類別實例,而且數個物件變數可以同時參考同一個類別實例。 當您透過指向相同實例的另一個變數來進行存取時,對類別成員值所做的變更會影響那些成員。
不過,結構元素會在自己的實例內隔離。 對其值所做的任何變更都不會反映在任何其他結構變數中,即使在同一個
Structure
宣告的其他實例中也是如此。相等。 兩個結構的相等測試必須使用「逐一比較元素」測試來執行。 您可以使用 Equals 方法來比較兩個物件變數。 Equals 可以指出兩個變數是否指向相同的實例。