Parameters: ByVal, ByRef, Optional, and ParamArray
Prerequisites: Subs and functions
ByVal and ByRef
By default, arguments are passed ByVal (by value): the procedure gets a copy, so assigning to the parameter doesn't affect the caller. ByRef passes the variable itself:
Module Program
Sub AddTenByVal(n As Integer)
n += 10
End Sub
Sub AddTenByRef(ByRef n As Integer)
n += 10
End Sub
Sub Main()
Dim a = 5
AddTenByVal(a)
Console.WriteLine(a)
AddTenByRef(a)
Console.WriteLine(a)
End Sub
End Module
5
15
ByVal is the default (VB6 defaulted to ByRef — a common source of
surprises when migrating). Use ByRef sparingly; returning a value
(or a tuple, Level 2) is usually clearer. Integer.TryParse is a
familiar example of a ByRef parameter.
Reference types passed ByVal
For an array or object, the reference is copied — so the procedure can still change the object's contents:
Module Program
Sub DoubleAll(values() As Integer)
For i = 0 To values.Length - 1
values(i) *= 2
Next
End Sub
Sub Main()
Dim nums = {1, 2, 3}
DoubleAll(nums)
Console.WriteLine(String.Join(" ", nums))
End Sub
End Module
2 4 6
Optional parameters and named arguments
Module Program
Function Greeting(name As String, Optional greetingWord As String = "Hello", Optional excited As Boolean = False) As String
Return $"{greetingWord}, {name}{If(excited, "!", ".")}"
End Function
Sub Main()
Console.WriteLine(Greeting("Ada"))
Console.WriteLine(Greeting("Ada", "Hi"))
Console.WriteLine(Greeting("Ada", excited:=True))
End Sub
End Module
Hello, Ada.
Hi, Ada.
Hello, Ada!
Optionalparameters need a default value and must come last.- Named arguments use
:=—excited:=Trueskips the parameters in between.
ParamArray
Module Program
Function Total(ParamArray values() As Integer) As Integer
Dim sum = 0
For Each v In values
sum += v
Next
Return sum
End Function
Sub Main()
Console.WriteLine(Total())
Console.WriteLine(Total(5))
Console.WriteLine(Total(1, 2, 3, 4))
End Sub
End Module
0
5
10
ParamArray accepts any number of arguments as an array — this is how
Console.WriteLine("{0} {1}", a, b) works.
Overloading
Several procedures can share a name if their parameter lists differ:
Module Program
Function Describe(n As Integer) As String
Return $"integer {n}"
End Function
Function Describe(s As String) As String
Return $"text '{s}'"
End Function
Sub Main()
Console.WriteLine(Describe(42))
Console.WriteLine(Describe("hi"))
End Sub
End Module
integer 42
text 'hi'