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...