共用方式為


逐步解說:使用 Visual Basic 撰寫元件

元件以物件的形式提供可重複使用的程式碼。 藉由建立物件及呼叫其屬性和方法來使用元件程式碼的應用程式,稱為「用戶端」(Client)。 用戶端與它所使用的元件不一定在同一個組件中。

下列程序將會相互建置,因此執行它們的順序是相當重要的。

注意事項注意事項

根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。 若要變更設定,請從 [工具] 功能表中選取 [匯入和匯出設定]。 如需詳細資訊,請參閱 使用設定

建立專案

若要建立 CDemoLib 類別庫及 CDemo 元件

  1. 在 [檔案] 功能表上選取 [新增],然後按一下 [專案] 以開啟 [新增專案] 對話方塊。 從 Visual Basic 專案類型清單選取 [類別庫] 專案範本,然後在 [名稱] 方塊中輸入 CDemoLib。

    注意事項注意事項

    建立新的專案時,一定要指定名稱。 如此可設定預設命名空間、組件名稱及專案名稱,同時也可確定預設元件會在正確的命名空間中。

  2. 在 [方案總管] 中以滑鼠右鍵按一下 [CDemoLib],並從捷徑功能表中選取 [屬性]。 請注意 [根命名空間] 方塊中包含有 [CDemoLib]。

    預設命名空間是用來限定組件中的元件名稱。 例如,若有兩個組件提供名為 CDemo 的元件,您就可以使用 CDemoLib.CDemo 指定 CDemo 元件。

    關閉對話方塊。

  3. 從 [專案] 功能表中選擇 [加入元件]。 選取 [加入新項目] 對話方塊中的 [元件類別],然後輸入 CDemo.vb (在 [名稱] 方塊中進行輸入)。 名為 CDemo 的元件會加入至您的類別庫。

  4. 在 [方案總管] 中按一下 [顯示所有檔案] 按鈕。 開啟 [CDemo.vb] 節點以顯示 [CDemo.Designer.vb] 檔案。 以滑鼠右鍵按一下 [CDemo.Designer.vb],並選擇捷徑功能表中的 [檢視程式碼]。 程式碼編輯器隨即開啟。

  5. 請注意 Inherits System.ComponentModel.Component 將緊接在 Partial Public Class CDemo 之下。 本章節指出您的類別所繼承之類別。 依照預設,元件繼承自系統所提供的 Component 類別。 Component 類別為您的元件提供許多功能,包括使用設計工具的能力。

  6. 找到 Public Sub New()。 選取整個方法主體,並按下 CTRL-X,將它從 CDemo.Designer.vb 檔案中剪下。

  7. 在 [方案總管] 中以滑鼠右鍵按一下 [CDemo.vb],然後選擇捷徑功能表上的 [檢視程式碼]。 程式碼編輯器立即開啟。

  8. 將選取範圍貼入 CDemo 類別的主體。 這能讓您使用 [新增],而不需要來自其他設計工具的介面。

  9. 在 [方案總管] 中,以滑鼠右鍵按一下 [Class1.vb],再選擇 [刪除]。 如此可刪除類別庫所提供的預設類別,因為在這個逐步解說中不會使用到。

  10. 從 [檔案] 功能表中選擇 [全部儲存] 以儲存專案。

加入建構函式和完成項

建構函式會控制元件的初始化方式,Finalize 方法則是控制元件的終止方式。 建構函式及 CDemo 類別之 Finalize 方法中的程式碼,會維護現存之 CDemo 物件個數的執行計數。

若要加入 CDemo 類別的建構函式和完成項的程式碼

  1. 在 [程式碼編輯器] 中,加入成員變數以維持 CDemo 類別之執行個體的執行總數,以及各執行個體的 ID 編號。

    Public ReadOnly InstanceID As Integer
    Private Shared NextInstanceID As Integer = 0
    Private Shared ClassInstanceCount As Long = 0
    

    由於 InstanceCount 及 NextInstanceID 成員變數是宣告為 Shared,所以它們只存在於類別層次。 存取這些成員之所有 CDemo 的執行個體將使用相同的記憶體位置。 在程式碼內第一次參考到 CDemo 類別時,會將共用成員初始化。 這可能是在第一次建立 CDemo 物件,或第一次存取其中一個共用成員時進行。

  2. 找到 CDemo 類別的預設建構函式 Public Sub New() 和 Public Sub New(Container As System.ComponentModel.IContainer)。 在 Visual Basic 中的所有建構函式 (Constructor) 都名為 New。 您的元件可以有數個具有不同參數的建構函式,但是名稱必須都是 New。

    注意事項注意事項

    建構函式的存取層級會判斷哪些用戶端可以建立類別的執行個體。 在 Visual Basic 的其他版本中,物件建立是由 Instancing 屬性決定。如果您已經使用 Instancing 屬性,閱讀 Visual Basic 中的元件執行個體變更可能會對您有幫助。

  3. 在建立新的 CDemo 並設定執行個體的 ID 編號時,將下列程式碼加入至 Sub New() 以增加執行個體的計數。

    注意事項注意事項

    永遠要將程式碼加在呼叫 InitializeComponent 之後。 此時,任何組成元件都已經初始化。

    InstanceID = NextInstanceID
    NextInstanceID += 1
    ClassInstanceCount += 1
    

    做為 ReadOnly 成員,InstanceID 只能在建構函式中設定。

    注意事項注意事項

    熟悉多執行緒處理的使用者將會正確指出,指派 InstanceID 及累加 NextInstanceID 應該是不可部分完成的作業 (Atomic Operation)。 這個及其他與執行緒相關的問題,會在逐步解說:使用 Visual Basic 撰寫簡單的多執行緒元件中加以說明。

  4. 在建構函式結尾處加入下列方法:

    Protected Overrides Sub Finalize()
       ClassInstanceCount -= 1
       End Sub
    

    記憶體管理員會在最後回收由 CDemo 物件所佔用的記憶體之前呼叫 FinalizeFinalize 方法是以 Object 做為起始,這是 .NET 類別階層中所有參考型別的根 (Root)。 透過覆寫 Finalize,就可以在從記憶體中移除元件之前先執行清除。 不過,稍後您將在這個逐步解說中了解,早一點釋放資源有其充分的原因。

將屬性加入至類別

CDemo 類別只有一個屬性,此屬性是共用屬性,可讓用戶端知道在任何指定的時間內,記憶體中有多少 CDemo 物件。 您也可以用類似的方式建立方法。

若要建立 CDemo 類別的屬性

  • 將下列屬性宣告加入至 CDemo 類別,使用戶端能擷取 CDemo 之執行個體的數目。

    Public Shared ReadOnly Property InstanceCount() As Long
       Get
          Return ClassInstanceCount
       End Get
    End Property
    
    注意事項注意事項

    屬性宣告語法與 Visual Basic 先前的版本中使用的不同。 如需對這個語法所做變更的詳細資訊,請參閱 Property Procedure Changes for Visual Basic 6.0 Users

測試元件

若要測試元件,您需要有使用該元件的專案。 此專案必須是您按下 [執行] 按鈕時,第一個啟動的專案。

若要加入 CDemoTest 用戶端專案做為方案的起始專案

  1. 在 [檔案] 功能表上指向 [新增],然後選擇 [新增專案] 以開啟 [加入新的專案] 對話方塊。

  2. 選取 [Windows 應用程式] 專案範本,然後在 [名稱] 方塊中輸入 [CDemoTest],接著再按一下 [確定]。

  3. 在 [方案總管] 中,以滑鼠右鍵按一下 [CDemoTest],然後按一下捷徑功能表上的 [設定為啟始專案]。

    為了要使用 CDemo 元件,用戶端測試專案必須具有類別庫專案的參考。 加入參考後,也可以將 Imports 陳述式加入測試應用程式以簡化元件的使用。

若要將參考加入至類別庫專案

  1. 在 [方案總管] 中按一下 [顯示所有檔案] 按鈕。 以滑鼠右鍵按一下緊接在 [CDemoTest] 下方的 [參考] 節點,然後在捷徑功能表中選取 [加入參考]。

  2. 在 [加入參考] 對話方塊中選取 [專案] 索引標籤。

  3. 按兩下 [CDemoLib] 類別庫專案。 [CDemoLib] 將會出現在 [CDemoTest] 專案的 [參考] 節點之下。

  4. 在 [方案總管] 中,以滑鼠右鍵按一下 [Form1.vb],然後從捷徑功能表選取 [檢視程式碼]。

    加入 CDemoLib 的參考可讓您使用 CDemo 元件的完整名稱,也就是 CDemoLib.CDemo。

若要加入 Imports 陳述式

  • 將下列 Imports 陳述式加入至 Form1 的 [程式碼編輯器] 最上方的 Class 宣告之上:

    Imports CDemoLib
    

    加入 Imports 陳述式可讓您省略程式庫名稱,並以 CDemo 指稱元件類型。 如需 Imports 陳述式的詳細資訊,請參閱 Visual Basic 中的命名空間

    現在,您將建立並使用測試程式來測試您的元件。

瞭解物件存留期

CDemoTest 程式將說明 .NET Framework 的物件存留期 (Lifetime),方法是建立及釋放大量的 CDemo 物件。

若要加入程式碼以建立和釋放 CDemo 物件

  1. 按一下 [Form1.vb [設計]] 返回設計工具。

  2. 從 [工具箱] 的 [所有 Windows Form] 索引標籤中,將 ButtonTimer 拖曳到 Form1 設計介面。

    非視覺化的 Timer 元件會顯示在表單下的個別設計介面上。

  3. 按兩下 [Timer1] 圖示,替 Timer1 元件的 Tick 事件建立事件處理方法。 將下列程式碼放置在事件處理方法中。

    Me.Text = "CDemo instances: " & CDemo.InstanceCount
    

    在計時器每次跳動時,表單的標題將顯示目前 CDemo 類別的執行個體計數。 類別名稱是做為共用之 InstanceCount 屬性的限定詞 (Qualifier) 使用,不需要建立 CDemo 的執行個體來存取共用成員。

  4. 按一下 [Form1.vb [設計]] 索引標籤,以返回設計工具。

  5. 以滑鼠右鍵按一下 Timer1,然後從捷徑功能表中選取 [屬性]。 在 [屬性] 視窗中,將 Enabled 屬性設定為 True。 如此,只要表單一建立,計時器將立刻啟動。

  6. 按兩下 Form1 上的 Button,替此按鈕的 Click 事件建立事件處理方法。 將下列程式碼放置在事件處理方法中。

    Dim cd As CDemo
    Dim ct As Integer
    For ct = 1 To 1000
       cd = New CDemo
    Next
    

    您可能覺得這個程式碼很陌生。 在每個 CDemo 的執行個體建立時,即會釋放前一個執行個體。 當 For 迴圈 (Loop) 結束之後,僅會留下一個 CDemo 的執行個體。 當事件處理方法存在時,甚至會釋放該執行個體,因為變數 cd 會超出範圍。

    不過您可能已經猜到,事情的發展不一定是這樣。

若要執行並偵錯 CDemoTest 和 CDemo 專案

  1. 請按 [F5] 以啟動方案。

    用戶端專案將啟動,並顯示 Form1。 請注意,表單的標題會顯示 "CDemo instances: 0"。

  2. 按一下這個按鈕。 表單的標題應該會顯示 "CDemo instances: 1000"。

    按鈕的 CDemo 事件處理程序結束時,Click 的執行個體應該已經全部釋放。 為什麼沒有終結它們? 簡單來說,記憶體管理員會在背景中,以低優先權終結物件。 只有當在系統的記憶體不足時,才會提高優先權。 此「暫緩」(Lazy) 的記憶體回收配置可提供極快速的物件配置。

  3. 多按按鈕幾次,注意看標題。 在某些時點上,執行個體的數目將會突然下降。 這表示記憶體管理員已歸還一些物件的記憶體。

    注意事項注意事項

    如果已經按了 10 次以上,而 CDemo 執行個體數目沒有減少,您可能需要調整程式碼,讓它可以使用更多的記憶體。 關閉表單返回開發環境,然後將 For 迴圈的重複次數增加到 10000, 然後再次執行專案。

  4. 重複步驟 3。 這次,在記憶體管理員終結更多的物件之前,您將可執行地更久。

    其實,您每重複步驟 3 一次,就可能在記憶體管理員介入之前分配更多的 CDemo 物件。 這是因為愈來愈多的 Visual Studio 被調換,留下更多空間給 CDemo 的執行個體使用。

  5. 關閉表單以返回開發環境。

請參閱

其他資源

使用元件進行程式設計

元件撰寫逐步解說