Function overloading in PowerShell Function overloading in PowerShell powershell powershell

Function overloading in PowerShell


In PowerShell functions are not overloaded. The last definition overrides the previous in the same scope or hides the previous in a parent scope. Thus, you should create a single function and provide a way to distinguish its call mode by arguments.

In V2 you may use an advanced function, see help about_Functions_Advanced_Parameters and avoid some manual coding on resolving parameter set ambiguities:

# advanced function with 3 parameter setsfunction Backup-UsersData(    [Parameter(Position=0, ParameterSetName="user")]    [string]$user,    [Parameter(Position=0, ParameterSetName="array")]    [object[]]$array,    [Parameter(Position=0, ParameterSetName="all")]    [switch]$all){    # use this to get the parameter set name    $PSCmdlet.ParameterSetName}# testBackup-UsersData -user 'John'Backup-UsersData 1, 2Backup-UsersData -all# OUTPUT:# user# array# all

Note that this mechanism is sometimes strange. For example in the first test we have to specify parameter name -user explicitly. Otherwise:

Backup-UsersData : Parameter set cannot be resolved using the specified named parameters.At C:\TEMP\_101015_110059\try2.ps1:21 char:17+ Backup-UsersData <<<<  'John'    + CategoryInfo          : InvalidArgument: (:) [Backup-UsersData], ParentContainsErrorRecordException    + FullyQualifiedErrorId : AmbiguousParameterSet,Backup-UsersData

In many cases standard, not advanced, function with mixed parameters will do:

function Backup-UsersData(    [string]$user,    [object[]]$array,    [switch]$all){    if ($user) {'user'}    elseif ($array) {'array'}    elseif ($all) {'all'}    else {'may be'}}Backup-UsersData -user 'John'Backup-UsersData -array 1, 2Backup-UsersData -allBackup-UsersData

But in this case you should resolve (or accept and ignore) ambiguities, e.g. to decide what to do if, say:

Backup-UsersData -user 'John' -array 1, 2 -all


Here is a variant of Roman's answer that I think is a little more flexible:

function Backup{    [CmdletBinding(DefaultParameterSetName='Users')]    Param (        [parameter(mandatory=$true, ParameterSetName='Users', position=0, ValueFromPipeline=$true)][string[]]$User,        [parameter(mandatory=$true, ParameterSetName='AllUsers')][switch]$All    )    Begin    {        if ($All) { $User = @('User1', 'User2', 'User3') }    }    Process    {        foreach ($u in $User)        {            echo "Backup $u"        }    }}


1) Build a class...

class c1 {     [int]f1( [string]$x ){ return 1 }     [int]f1( [int ]$x ){ return 2 }    }

1+) Use STATIC METHODS if you prefer to call them without instantiation...

class c1 {     static [int] f1( [string]$x ){ return 1 }     static [int] f1( [int]$x ){ return 2 }     }

2) Call the methods in class or object... overload works OK

$o1 = [c1]::new()o1.f1( "abc" ) ~> returns 1o1.f1( 123 )   ~> returns 2

-OR-


[c1]::f1( "abc" ) ~> returns 1[c1]::f1( 123 )   ~> returns 2

3)If (like me)
you want to have "Overloaded Functions" placed in a libraries...
so your users can use them transparently...
from code or from Interactive Command Line (REPL)...

the closest I could came to
"Overloading functions in Powershell"
was something like this:

function Alert-String() { [c1]::f1( "abc" ) }function Alert-Strings(){ [c1]::f1( 123 ) }function Alert-Stringn(){ [c1]::f1( 123 ) }

Maybe in PS-Core v8??? ;-)

Hope it helps...