When you overload a procedure, you must use a different signature for each overloaded version. This usually means each version must specify a different parameter list. For more information, see "Different Signature" in Procedure Overloading.

You can overload a Function procedure with a Sub procedure, and vice versa, provided they have different signatures. Two overloads cannot differ only in that one has a return value and the other does not.

You can overload a property the same way you overload a procedure, and with the same restrictions. However, you cannot overload a procedure with a property, or vice versa.

You sometimes have alternatives to overloaded versions, particularly when the presence of arguments is optional or their number is variable.

Keep in mind that optional arguments are not necessarily supported by all languages, and parameter arrays are limited to Visual Basic. If you are writing a procedure that is likely to be called from code written in any of several different languages, overloaded versions offer the greatest flexibility.

When the calling code can optionally supply or omit one or more arguments, you can define multiple overloaded versions or use optional parameters.

#### When to Use Overloaded Versions

You can consider defining a series of overloaded versions in the following cases:

• The logic in the procedure code is significantly different depending on whether the calling code supplies an optional argument or not.

• The procedure code cannot reliably test whether the calling code has supplied an optional argument. This is the case, for example, if there is no possible candidate for a default value that the calling code could not be expected to supply.

#### When to Use Optional Parameters

You might prefer one or more optional parameters in the following cases:

• The only required action when the calling code does not supply an optional argument is to set the parameter to a default value. In such a case, the procedure code can be less complicated if you define a single version with one or more Optional parameters.

When the calling code can pass a variable number of arguments, you can define multiple overloaded versions or use a parameter array.

#### When to Use Overloaded Versions

You can consider defining a series of overloaded versions in the following cases:

• You know that the calling code never passes more than a small number of values to the parameter array.

• The logic in the procedure code is significantly different depending on how many values the calling code passes.

• The calling code can pass values of different data types.

#### When to Use a Parameter Array

You are better served by a ParamArray parameter in the following cases:

• You are not able to predict how many values the calling code can pass to the parameter array, and it could be a large number.

• The procedure logic lends itself to iterating through all the values the calling code passes, performing essentially the same operations on every value.

## Implicit Overloads for Optional Parameters

A procedure with an Optional parameter is equivalent to two overloaded procedures, one with the optional parameter and one without it. You cannot overload such a procedure with a parameter list corresponding to either of these. The following declarations illustrate this.

Overloads Sub q(ByVal b As Byte, Optional ByVal j As Long = 6)

' The preceding definition is equivalent to the following two overloads.
' Overloads Sub q(ByVal b As Byte)
' Overloads Sub q(ByVal b As Byte, ByVal j As Long)

' Therefore, the following overload is not valid because the signature is already in use.
' Overloads Sub q(ByVal c As Byte, ByVal k As Long)
' The following overload uses a different signature and is valid.
Overloads Sub q(ByVal b As Byte, ByVal j As Long, ByVal s As Single)


For a procedure with more than one optional parameter, there is a set of implicit overloads, arrived at by logic similar to that in the preceding example.

## Implicit Overloads for a ParamArray Parameter

The compiler considers a procedure with a ParamArray parameter to have an infinite number of overloads, differing from each other in what the calling code passes to the parameter array, as follows:

• One overload for when the calling code does not supply an argument to the ParamArray

• One overload for when the calling code supplies a one-dimensional array of the ParamArray element type

• For every positive integer, one overload for when the calling code supplies that number of arguments, each of the ParamArray element type

The following declarations illustrate these implicit overloads.

Overloads Sub p(ByVal d As Date, ByVal ParamArray c() As Char)

' The preceding definition is equivalent to the following overloads.
' Overloads Sub p(ByVal d As Date)
' Overloads Sub p(ByVal d As Date, ByVal c() As Char)
' Overloads Sub p(ByVal d As Date, ByVal c1 As Char)
' Overloads Sub p(ByVal d As Date, ByVal c1 As Char, ByVal c2 As Char)
' And so on, with an additional Char argument in each successive overload.


You cannot overload such a procedure with a parameter list that takes a one-dimensional array for the parameter array. However, you can use the signatures of the other implicit overloads. The following declarations illustrate this.

' The following overload is not valid because it takes an array for the parameter array.
' Overloads Sub p(ByVal x As Date, ByVal y() As Char)
' The following overload takes a single value for the parameter array and is valid.
Overloads Sub p(ByVal z As Date, ByVal w As Char)


If you want to allow the calling code to pass different data types to a parameter, an alternative approach is typeless programming. You can set the type checking switch to Off with either the Option Strict Statement or the /optionstrict compiler option. Then you do not have to declare the parameter's data type. However, this approach has the following disadvantages compared to overloading: