Skip to content
AgileLogics
6 min read

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!
  • Optional parameters need a default value and must come last.
  • Named arguments use := — excited:=True skips 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'