3 votes

Pourquoi la valeur du paramètre de type "switch" est-elle passée à un paramètre de type chaîne de caractères ?

Le code de test ( test.ps1 ):

Param(
    [string]$content = $null,
    [switch]$flag = $false
)
Write-Host $content

Sortie :

PS C:\\Users\\powershell> .\\test.ps1

PS C:\\Users\\powershell> .\\test.ps1 -flag $true    
True
PS C:\\Users\\powershell> .\\test.ps1 -flag $false
False
PS C:\\Users\\powershell> .\\test.ps1 -flag $true -content "lalala"
lalala

Peu importe que je mette $content à $null ou "" ou sans aucune valeur par défaut, le résultat est le même.

Alors pourquoi $content prendre la valeur de $flag ?

7voto

Ansgar Wiechers Points 38466

@PetSerAl a déjà indiqué quel était votre malentendu, mais peut-être était-ce un peu trop bref, alors je vais développer un peu plus.

A [switch] ne prend pas de valeur comme les paramètres ordinaires. Vous le définissez normalement à true ou false respectivement en fournissant ou en omettant le paramètre :

PS C:\\> **Get-Content .\\test.ps1**
Param(
    \[string\]$Content = $null,
    \[switch\]$Flag
)
$flag.IsPresent
$Content
PS C:\\> **.\\test.ps1**
False

PS C:\\> **.\\test.ps1 -Flag**
True

Vous pouvez également transmettre explicitement une valeur en mettant deux points entre le paramètre de commutation et la valeur :

PS C:\\> **.\\test.ps1 -Flag:$false**
False

PS C:\\> **.\\test.ps1 -Flag:$true**
True

Les espaces blancs après les deux points sont autorisés, mais pas avant ( -Flag: $false passe $false comme valeur de commutation, -Flag :$false ne le fait pas).

Si vous essayez d'assigner la valeur du commutateur sans les deux-points, la valeur est en fait transmise au paramètre suivant dans la ligne, dans votre cas le -Content paramètre :

PS C:\\> **.\\test.ps1 -Flag $false**
True         _\# value of the parameter $Flag_
False        _\# value of the (positional) parameter $Content_
PS C:\\> **.\\test.ps1 -Flag -Content $false**
True         _\# value of the parameter $Flag_
False        _\# value of the (named) parameter $Content_

Si vous utilisez -Flag $true (sans les deux points) y passer une valeur au paramètre (nommé) -Content la valeur $true est passé en tant que troisième paramètre sans nom (accessible via la balise variable automatique $args ), comme si vous aviez mis la valeur à la fin de la déclaration :

PS C:\\> **Get-Content .\\test2.ps1**
Param(
    \[string\]$Content = $null,
    \[switch\]$Flag
)
$flag.IsPresent
$Content
$args\[0\]
PS C:\\> **.\\test2.ps1 -Flag $false -Content 'something'**
True
something
False        _\# $false passed as unnamed 3rd parameter_
PS C:\\> **.\\test2.ps1 -Flag:$false -Content 'something'**
False        _\# $false passed as explicit value of switch parameter $Flag_
something
PS C:\\> **.\\test2.ps1 -Flag -Content 'something' $false**
True
something
False        _\# $false passed as unnamed 3rd parameter_

2voto

gms0ulman Points 7505

Exécutez ce code de test, en l'appelant comme vous l'avez fait dans la question. Ajoutez ce test :

C:\Users\powershell> .\test.ps1 -flag

script illustrera les points suivants :

  • Selon le commentaire de 4c74356b41, les commutateurs sont $false sauf si cela est spécifié sur la ligne de commande. Ainsi, -flag définit le $flag sur vrai ; -flag $true met l'indicateur à true y passe l'argument $true au contenu.
  • A partir de là, pas besoin de préciser $flag=$false dans script params
  • Ajout d'un test pour que vous puissiez voir quand $content est vide/nul car il n'y a pas non plus besoin de $content=$null

param(
    [string]$content,
    [switch]$flag
)

$test = [string]::IsNullOrEmpty($content)

Write-Output "content: $content"
Write-Output "flag   : $flag"
Write-Output "Is content null: $test"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X