Section 7.13. Passing Arguments: Pass-by-Value vs. Pass-by-Reference


7.13. Passing Arguments: Pass-by-Value vs. Pass-by-Reference

Arguments are passed in one of two ways: pass-by-value and pass-by-reference. When an argument is passed by value, the program makes a copy of the argument's value and passes the copy to the called method. With pass-by-value, changes to the called method's copy do not affect the original variable's value in the caller. In contrast, when an argument is passed by reference, the caller gives the called method the ability to access and modify the caller's original data directly. Fig. 7.10 demonstrates passing value-type arguments by value and by reference.

Figure 7.10. ByVal and ByRef used to pass value-type arguments.

  1  ' Fig. 7.10: ByRefTest.vb  2  ' Demonstrates passing by value and by reference.  3  Module ByRefTest  4     Sub Main()  5        Dim number1 As Integer = 2  6  7        Console.WriteLine("Passing a value-type argument by value:")  8        Console.WriteLine("Before calling SquareByValue, " & _  9           "number1 is {0}", number1) 10        SquareByValue(number1)  ' passes number1 by value 11        Console.WriteLine("After returning from SquareByValue, " & _ 12           "number1 is {0}" & vbCrLf, number1) 13 14        Dim number2 As Integer = 2 15 16        Console.WriteLine("Passing a value-type argument" & _ 17           " by reference:") 18        Console.WriteLine("Before calling SquareByReference, " & _ 19           "number2 is {0}", number2) 20        SquareByReference(number2) ' passes number2 by reference 21        Console.WriteLine("After returning from " & _ 22           "SquareByReference, number2 is {0}" & vbCrLf, number2) 23 24        Dim number3 As Integer = 2 25 26        Console.WriteLine("Passing a value-type argument" & _ 27           " by reference, but in  parentheses:") 28        Console.WriteLine("Before  calling SquareByReference " & _ 29           "using parentheses, number3 is {0}", number3) 30        SquareByReference((number3)) ' passes number3 by value 31        Console.WriteLine("After returning from " & _ 32           "SquareByReference, number3 is {0}", number3) 33     End Sub ' Main 34 35     ' squares number by value (note ByVal keyword) 36     Sub SquareByValue(ByVal number As Integer) 37        Console.WriteLine("After entering SquareByValue, " & _ 38           "number is {0}", number) 39        number *= number 40        Console.WriteLine("Before  exiting SquareByValue, " & _ 41           "number is {0}", number) 42     End Sub ' SquareByValue 43 44     ' squares number by reference (note ByRef keyword) 45     Sub SquareByReference(ByRef number As Integer) 46        Console.WriteLine("After entering SquareByReference" & _ 47           ", number is {0}", number) 48        number *= number 49        Console.WriteLine("Before  exiting SquareByReference" & _ 50           ", number is {0}", number) 51     End Sub ' SquareByReference 52  End Module ' ByRefTest 

[View full width]

Passing a value-type argument by value: Before calling SquareByValue, number1 is 2 After entering SquareByValue, number is 2 Before exiting SquareByValue, number is 4 After returning from SquareByValue, number1 is 2 Passing a value-type argument by reference: Before calling SquareByReference, number2 is 2 After entering SquareByReference, number is 2 Before exiting SquareByReference, number is 4 After returning from SquareByReference, number2 is 4 Passing a value-type argument by reference, but in parentheses: Before calling SquareByReference using parentheses , number3 is 2 After entering SquareByReference, number is 2 Before exiting SquareByReference, number is 4 After returning from SquareByReference, number3 is 2



The program passes three value-type variables, number1, number2 and number3, in different ways to methods SquareByValue (lines 3642) and SquareByReference (lines 4551). Keyword ByVal in the method header of SquareByValue (line 36) indicates that value-type arguments should be passed by value. A parameter declared with keyword ByVal is known as a value parameter. When number1 is passed to SquareByValue (line 10), a copy of the value stored in number1 (i.e., 2) is passed to the method. Therefore, the value of number1 in the calling method, Main, is not modified when parameter number is squared in method SquareByValue (line 39)only the local copy stored in parameter number gets modified.

Method SquareByReference uses keyword ByRef (line 45) to receive its value-type parameter by reference. A parameter declared with keyword ByRef is known as a reference parameter. When Main calls SquareByReference (line 20), a reference to the value stored in number2 is passed, which gives SquareByReference direct access to the value stored in the original variable. Thus, the value stored in number2 after SquareByReference finishes executing is the same as the final value of parameter number.

When arguments are enclosed in parentheses, (), the expression within the parentheses is evaluated. In line 30, the inner set of parentheses evaluates number3 to its value (2) and passes this value to the method, even if the method header includes keyword ByRef. Thus, the value of number3 does not change after it is passed to SquareByReference (line 30) via parentheses.

Passing value-type arguments with keyword ByRef is useful when methods need to alter argument values directly. However, passing by reference can weaken security, because the called method can modify the caller's data. We discuss some of the more complex subtleties of passing arguments by value and by reference in Section 8.14.

When you pass a variable of a reference type to a method that declares the corresponding parameter ByVal, a copy of the variable's value is passed. In this case, the value is actually a reference to an object, so the method is able to modify the object in memory. Thus, reference-type variables passed with keyword ByVal are effectively passed by reference. Although Visual Basic allows you to use keyword ByRef with reference-type parameters, it is usually not necessary to do so except with type String. Although they technically are reference types, String arguments cannot be modified directly when passed with keyword ByVal, due to some subtle details of the String type, which we discuss in Chapter 16, Strings, Characters and Regular Expressions. We discuss passing reference types by reference in Section 8.14.

Error-Prevention Tip 7.4

When passing arguments by value, changes to the called method's copy do not affect the original variable's value. This prevents possible side effects that could hinder the development of correct and reliable software systems. Always pass value-type arguments by value unless you explicitly intend for the called method to modify the caller's data.




Visual BasicR 2005 for Programmers. DeitelR Developer Series
Visual Basic 2005 for Programmers (2nd Edition)
ISBN: 013225140X
EAN: 2147483647
Year: 2004
Pages: 435

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net