2010-10-15 6 views
22

Peut-on surcharger des fonctions dans PowerShell?Surcharge de la fonction dans PowerShell

Je veux que ma fonction accepte une chaîne, un tableau ou un commutateur.

Un exemple de ce que je veux:

  • sauvegarde-UsersData
  • mono-utilisateur @ sauvegarde-UsersData ('Alice', 'Bob', 'Joe')
  • sauvegarde-UsersData -Tous
+1

« Jeux de paramètres » sont essentiellement équivalents à la surcharge de méthode OO. Ils sont parfois un peu plus compliqués à cause du puissant parser de coercition de type poewrshell. – x0n

Répondre

25

Dans PowerShell, les fonctions ne sont pas surchargées. La dernière définition remplace la précédente dans la même étendue ou masque la précédente dans une étendue parent. Ainsi, vous devriez créer une seule fonction et fournir un moyen de distinguer son mode d'appel par des arguments.

Dans V2 vous pouvez utiliser une fonction avancée, voir help about_Functions_Advanced_Parameters et d'éviter certains codage manuel sur la résolution des ambiguïtés du jeu de paramètres:

# advanced function with 3 parameter sets 
function 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 
} 

# test 
Backup-UsersData -user 'John' 
Backup-UsersData 1, 2 
Backup-UsersData -all 

# OUTPUT: 
# user 
# array 
# all 

Notez que ce mécanisme est parfois étrange. Par exemple, dans le premier test, nous devons spécifier le nom du paramètre -user explicitement. Dans le cas contraire:

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 

Dans de nombreux cas standard, non avancé, fonction des paramètres mixtes feront:

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, 2 
Backup-UsersData -all 
Backup-UsersData 

Mais dans ce cas, vous devez résoudre les ambiguïtés (ou d'accepter et d'ignorer), par exemple de décider quoi faire si, par exemple:

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

Voici une variante de la réponse de Roman que je pense est un peu plus souple:

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" 
     } 
    } 
}