當您呼叫程式時,您提供的每個自變數都會對應至程式中定義的其中一個參數。 在某些情況下,程式代碼可以變更呼叫程式代碼中自變數的基礎值。 在其他情況下,程式只能變更其自變數的本機複本。
當您呼叫程式時,Visual Basic 會建立 ByVal 所傳遞之每個自變數的本機複本。 針對傳遞 ByRef 的每個參數,Visual Basic 會為該程式碼提供呼叫程式碼中參數所依據的程式設計元素的直接引用。
如果呼叫程式碼中的基礎元素是可修改的,而且參數 ByRef 被傳遞,那麼程序碼可以使用直接參考來變更呼叫程式碼中的元素值。
變更基礎值
變更呼叫程式代碼中程式自變數的基礎值
在程式宣告中,針對對應自變數的參數指定 ByRef 。
在呼叫程式碼時,傳遞可修改的程式設計元素作為參數。
在呼叫程式代碼中,請勿在自變數清單中以括弧括住自變數。
在程式代碼中,使用參數名稱將值指派給呼叫程式代碼中的基礎元素。
如需示範,請參閱進一步的範例。
更改在地副本
如果呼叫程式代碼中的基礎專案是不可修改的專案,或傳遞 ByVal自變數,則程式無法在呼叫程式代碼中變更其值。 不過,程式可以變更其這類自變數的本機複本。
變更程式代碼中程式自變數的複本
在程式宣告中,針對對應至 自變數的參數指定 ByVal 。
-或-
在呼叫程式代碼中,將自變數括在自變數清單中括弧中。 這會強制 Visual Basic 以傳值方式傳遞自變數,即使對應的參數指定
ByRef也一樣。在程式代碼中,使用參數名稱將值指派給自變數的本機複本。 呼叫程式代碼中的基礎值不會變更。
範例
下列範例顯示兩個程序,它們接收陣列變數並操作其元素。 程式 increase 只會將一個新增至每個元素。 此 replace 程序會將新的陣列指派給參數 a(),然後將每個元素加一。
Public Sub increase(ByVal a() As Long)
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Public Sub replace(ByRef a() As Long)
Dim k() As Long = {100, 200, 300}
a = k
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
第一個 MsgBox 呼叫會顯示「n 增加後:11、21、31、41」。 因為陣列 n 是參考型別, replace 即使傳遞機制是 ByVal,也可以變更其成員。
第二個 MsgBox 呼叫會顯示 「After replace(n): 101, 201, 301」。 因為 n 被傳遞到 ByRef,所以 replace 可以修改呼叫程式碼中的變數 n,並將新的陣列指派給它。 因為 n 是參考型別, replace 因此也可以變更其成員。
您可以防止程式修改呼叫程式代碼中的變數本身。 請參閱 如何:保護程式自變數不受值變更。
編譯程式碼
當您以傳址方式傳遞變數時,必須使用 ByRef 關鍵詞來指定此機制。
Visual Basic 中的預設值是依值傳遞自變數。 然而,在每個宣告的參數中加入 ByVal 或 ByRef 關鍵詞是很好的程式設計做法。 這可讓您的程式代碼更容易閱讀。
.NET Framework 安全性
允許程式變更呼叫程式代碼中自變數的基礎值時,一律會有潛在的風險。 請確定您預期此值會變更,並準備好在使用它之前檢查其有效性。