按值和按參照傳遞參數 (Visual Basic)

在 Visual Basic 中,您可以將參數 依值或依參考的方式傳遞至程序。 這稱為 傳遞機制,它會判斷程序是否可以修改呼叫代碼中參數的基礎程式元素。 程式宣告會藉由指定 ByVal 或 ByRef 關鍵詞來判斷每個參數的傳遞機制。

區別

將自變數傳遞至程式時,請注意彼此互動的幾種不同差異:

  • 程式元件是否可修改或不可修改

  • 自變數本身是否可修改或不可修改

  • 函數參數是以傳值或按引用方式傳遞

  • 自變數數據類型是實值型別還是引用型別

如需詳細資訊,請參閱 可修改參數與不可修改參數之間的差異,以及 依值傳遞參數與依參考傳遞之間的差異。

選擇傳遞機制

您應該為每個參數仔細選擇傳遞方式。

  • 保護。 在選擇兩個傳遞機制時,最重要的準則是呼叫變數被更改的程度。 傳遞自變數 ByRef 的優點是程式可以透過該自變數將值傳回呼叫端程序代碼。 傳遞自變數 ByVal 的優點是它會保護變數不受程序變更。

  • 效能。 雖然傳遞機制可能會影響程式代碼的效能,但差異通常微不足道。 其中一個例外狀況是傳遞的實值型別 ByVal。 在此情況下,Visual Basic 會複製自變數的整個數據內容。 因此,對於結構之類的大型數值類型,傳遞它會更有效率 ByRef。

    針對參考型別,只會複製數據的指標(32 位平臺上有四個字節,64 位平臺上有8個字節)。 因此,您可以按值傳遞型String或Object的參數,而不會影響效能。

判斷傳遞機制

程式宣告會指定每個參數的傳遞機制。 呼叫程式碼無法覆寫 ByVal 機制。

如果 ByRef 用於宣告參數,則呼叫端代碼可以透過在呼叫中將參數名稱用括號括住來強制使用機制 ByVal。 如需詳細資訊,請參閱 如何:強制以傳值方式傳遞自變數。

Visual Basic 中的預設值是依值傳遞自變數。

何時依值傳遞參數

  • 如果自變數基礎的呼叫程式代碼專案是不可修改的專案,請宣告對應的參數 ByVal。 沒有程式代碼可以變更無法修改元素的值。

  • 如果基礎專案是可修改的,但您不希望程式能夠變更其值,請宣告 參數 ByVal。 只有呼叫程式碼可以變更以值傳遞的可修改元素的值。

以參考方式傳遞參數的時機

  • 如果程式確實需要變更呼叫程式代碼中的基礎元素,請宣告對應的參數 ByRef。

  • 如果程式代碼的正確執行取決於變更呼叫程式代碼中基礎元素的程式,請宣告 參數 ByRef。 如果您以傳值方式傳遞它,或呼叫程式代碼以括弧括住自變數來覆寫 ByRef 傳遞機制,則過程調用可能會產生非預期的結果。

範例

說明

下列範例說明何時依值傳遞自變數,以及何時以傳址方式傳遞自變數。 程序 Calculate 同時具有 ByVal 和 ByRef 參數。 給定利率 rate 和金額 debt,程式的工作是計算套用利率至原始值 debt的結果,以獲得新值 debt。 因為 debt 是 ByRef 參數,因此新的總計會反映在對應至 debt的呼叫程式代碼中自變數的值。 參數 rate 是一個 ByVal 參數,因為 Calculate 的值不應該改變。

Code

Module Module1

    Sub Main()
        ' Two interest rates are declared, one a constant and one a 
        ' variable.
        Const highRate As Double = 12.5
        Dim lowRate = highRate * 0.6

        Dim initialDebt = 4999.99
        ' Make a copy of the original value of the debt.
        Dim debtWithInterest = initialDebt

        ' Calculate the total debt with the high interest rate applied.
        ' Argument highRate is a constant, which is appropriate for a 
        ' ByVal parameter. Argument debtWithInterest must be a variable
        ' because the procedure will change its value to the calculated
        ' total with interest applied.
        Calculate(highRate, debtWithInterest)
        ' Format the result to represent currency, and display it.
        Dim debtString = Format(debtWithInterest, "C")
        Console.WriteLine("What I owe with high interest: " & debtString)

        ' Repeat the process with lowRate. Argument lowRate is not a 
        ' constant, but the ByVal parameter protects it from accidental
        ' or intentional change by the procedure. 

        ' Set debtWithInterest back to the original value.
        debtWithInterest = initialDebt
        Calculate(lowRate, debtWithInterest)
        debtString = Format(debtWithInterest, "C")
        Console.WriteLine("What I owe with low interest:  " & debtString)
    End Sub

    ' Parameter rate is a ByVal parameter because the procedure should
    ' not change the value of the corresponding argument in the 
    ' calling code. 

    ' The calculated value of the debt parameter, however, should be
    ' reflected in the value of the corresponding argument in the 
    ' calling code. Therefore, it must be declared ByRef. 
    Sub Calculate(ByVal rate As Double, ByRef debt As Double)
        debt = debt + (debt * rate / 100)
    End Sub

End Module

另請參閱