Section 4.7. Parameters and Arguments


4.7. Parameters and Arguments

Although procedures are self-contained blocks of code, they often need to interact with data from outside of the procedure. External data can be passed into the procedure through its parameter list. This list appears immediately on the declaration line of the procedure itself.

     Public Function RepeatString(ByVal origText As String, _           ByVal howManyTimes As Integer) As String        ' ----- Return a string concatenated to itself many times.        Dim counter As Integer        RepeatString = ""        For counter = 1 To howManyTimes           RepeatString &= origText        Next counter     End Function 

The RepeatString function includes two parameters, origText and howManyTimes. Each parameter includes a data type and a passing method. The passing method is either ByVal ("by value") or ByRef ("by reference"). In .NET, the default parameter passing method is ByVal.

When calling a procedure that has parameters, the values you send from the initiating code are called arguments. The following statement includes two arguments in the call to the RepeatString function: a string ("abc") and an integer (5).

     targetString = RepeatString("abc", 5) 

Because classes in .NET support overloaded methods, the arguments you send to a procedure must match the parameter signature of one of the overloaded methods. See Chapter 3 for a broader discussion of overloading.

4.7.1. Passing Arguments

All arguments are passed by value or by reference, depending on whether the ByVal or ByRef keyword is used with a parameter. When data is passed by value, a copy of the source expression or variable is sent to the target procedure. While in that procedure, the parameter acts just like a local variable; it can be examined and modified within the procedure, and it disappears when the procedure is finished. Any changes made to a ByVal parameter in the procedure are not reflected in the source variable. This is clearest when working with value types. Consider the following code.

     Public Sub ParentRoutine(  )        Dim sourceValue As Integer = 5        ChildRoutine(sourceValue)        MsgBox(sourceValue)   ' --> Displays "5"     End Sub     Public Sub ChildRoutine(ByVal incoming As Integer)        incoming = 10     End Sub 

Even though sourceValue was passed to ChildRoutine, and its associated parameter incoming was modified, that change did not propagate back to ParentRoutine, since incoming contained only a copy of sourceValue's value.

Objects (reference types) passed into routines ByVal, however, can be modified by the target procedure. More correctly, the members of an object can be modified, not the object itself. Objects passed by value pass the memory location of the object, so changes made within that memory area in the target procedure are reflected in the original object. However, you cannot fully replace the object with a new object instance when using ByVal.

     Public Class DataClass        Public DataMember As Integer     End Class     Public Class CodeClass        Public Sub ParentRoutine(  )           Dim sourceValue As New DataClass           sourceValue.DataMember = 5           ChildRoutine(sourceValue)           MsgBox(sourceValue.DataMember)   ' --> Displays "10"        End Sub        Public Sub ChildRoutine(ByVal incoming As DataClass)           ' ----- This line changes the "real" member.           incoming.DataMember = 10           ' ----- But these lines have no impact on sourceValue.           incoming = New DataClass           incoming.DataMember = 15        End Sub     End Class 

Passing a value type argument to a procedure with a ByRef parameter passes the memory address of the value; changes made in the target procedure are reflected immediately in the source value. (This is true if the source value is a variable; constants and calculated expressions cannot be modified.) Contrast the following code with its ByVal counterpart above.

     Public Sub ParentRoutine(  )        Dim sourceValue As Integer = 5        ChildRoutine(sourceValue)        MsgBox(sourceValue)   ' --> Displays "10"     End Sub     Public Sub ChildRoutine(ByRef incoming As Integer)        incoming = 10     End Sub 

Changing ByVal to ByRef made a significant difference. For reference types, the difference is not as noticeable unless you attempt to fully replace the original object in the target procedure. You can do it! This is because the ByRef keyword causes the memory address of the memory address of the object to be passed in. If you modify that memory address, you replace the address managed by the source variable. In some languages, this is referred to as a double pointer. It's somewhat confusing, but an example should make it clear. Contrast this code with the similar ByVal code shown earlier.

     Public Class DataClass        Public DataMember As Integer     End Class     Public Class CodeClass        Public Sub ParentRoutine(  )           Dim sourceValue As New DataClass           sourceValue.DataMember = 5           ChildRoutine(sourceValue)           MsgBox(sourceValue.DataMember)   ' --> Displays "15"        End Sub        Public Sub ChildRoutine(ByRef incoming As DataClass)           ' ----- This line changes the "real" member.           incoming.DataMember = 10           ' ----- These lines fully replace the object referred           '       to by sourceValue.           incoming = New DataClass           incoming.DataMember = 15        End Sub     End Class 

Using ByRef with reference types allows the target procedure to fully replace the original object with a completely new instance of an object.

4.7.2. Optional Arguments

Visual Basic supports optional parameters through the Optional keyword.

     Sub Calculate(Optional ByVal silent As Boolean = False) 

The following rules apply to optional arguments:

  • Every optional argument must specify a default value, and this default must be a constant expression (not a variable). This value is used when the calling code does not supply an argument for the optional parameter.

  • Every argument following an optional argument must also be optional. All required arguments must appear before the optional arguments in the parameter list.

Pre-.NET versions of VB allowed you to omit the default value, and, if the parameter was of type Variant, you could use the IsMissing function to determine if a value was supplied. This is no longer supported; if an argument is not supplied, the required default value is used instead.

4.7.3. Parameter Arrays

Normally, a procedure definition specifies a fixed number of parameters. However, the ParamArray ("parameter array") keyword allows the parameter list to be extended beyond the fixed elements. Each call to the procedure can use a different number of parameters beyond any initial required parameters.

Consider a function that takes the average of a number of test scores, but the number of scores may vary.

     Public Function AverageScore(ByVal ParamArray scores(  ) _           As Single) As Single        ' ----- Calculate the average score for any number of tests.        Dim counter As Integer        AverageScore = 0        For counter = 0 To UBound(scores)           AverageScore += scores(counter)        Next counter        AverageScore /= UBound(scores) + 1     End Function 

The call to AverageScore can now include a varied number of arguments.

     MsgBox(AverageScore(1, 2, 3, 4, 5))  ' --> Displays "3"     MsgBox(AverageScore(1, 2, 3))        ' --> Displays "2" 

The following rules apply to the use of ParamArray:

  • A procedure can only have one parameter array, and it must be the last parameter in the parameter list.

  • The parameter array must be passed by value, and you must explicitly include ByVal in the procedure definition.

  • The parameter array must be a one-dimensional array. If the type is not declared, it is assumed to be System.Object.

The parameter array is automatically optional. Its default value is an empty one-dimensional array of the parameter array's data type.




Visual Basic 2005(c) In a Nutshell
Visual Basic 2005 in a Nutshell (In a Nutshell (OReilly))
ISBN: 059610152X
EAN: 2147483647
Year: 2004
Pages: 712

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