Coalescence nulle dans Powershell

Existe-t-il un opérateur de coalescence nul dans powershell?

Je voudrais pouvoir faire ces commandes c # dans Powershell:

var s = myval ?? "new value"; var x = myval == null ? "" : otherval; 

Pas besoin des extensions de communauté Powershell, vous pouvez utiliser les instructions if standard de Powershell en tant qu’expression:

 variable = if (condition) { expr1 } else { expr2 } 

Donc, pour les remplacements de votre première expression est:

 var s = myval ?? "new value"; 

devient l’un des suivants (selon la préférence):

 $s = if ($myval -eq $null) { "new value" } else { $myval } $s = if ($myval -ne $null) { $myval } else { "new value" } 

ou en fonction de ce que $ myval peut contenir, vous pouvez utiliser:

 $s = if ($myval) { $myval } else { "new value" } 

et la deuxième expression est similaire:

 var x = myval == null ? "" : otherval; 

devient

 $x = if ($myval -eq $null) { "" } else { $otherval } 

Maintenant, pour être juste, ce ne sont pas très faciles à utiliser, et rien n’est aussi confortable à utiliser que les formulaires C #.

Vous pourriez aussi envisager de l’emballer dans une fonction très simple pour rendre les choses plus lisibles:

 function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } } $s = Coalesce $myval "new value" 

ou éventuellement comme, IfNull:

 function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } } $s = IfNull $myval "new value" $myval $x = IfNull $myval "" $otherval 

Comme vous pouvez le voir, une fonction très simple peut vous donner une certaine liberté de syntaxe.

UPDATE: Une option supplémentaire à considérer dans le mix est une fonction IsTrue plus générique:

 function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } } $x = IfTrue ($myval -eq $null) "" $otherval 

Ensuite, combiner la capacité de Powershell à déclarer des alias qui ressemblent à des opérateurs, vous vous retrouvez avec:

 New-Alias "??" Coalesce $s = ?? $myval "new value" New-Alias "?:" IfTrue $ans = ?: ($q -eq "meaning of life") 42 $otherval 

Clairement, cela ne va pas être au goût de tous, mais peut-être ce que vous recherchez.

Oui, PowerShell possède un opérateur de coalescence null, ou au moins un opérateur capable de ce type de comportement. Cet opérateur est -ne :

 # Format: # ($a, $b, $c -ne $null)[0] ($null, 'alpha', 1 -ne $null)[0] # Output: alpha 

C’est un peu plus polyvalent qu’un opérateur de coalescence null, car il crée un tableau de tous les éléments non nuls:

 $items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false $instances = $items -ne $null [ssortingng]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() })) # Result: System.Ssortingng, System.Int32, System.Int32, System.Ssortingng, System.Object[], System.Boolean, System.Boolean 

-eq fonctionne de manière similaire, ce qui est utile pour compter les entrées nulles:

 ($null, 'a', $null -eq $null).Length # Result: 2 

Mais de toute façon, voici un cas typique pour refléter les C # opérateur:

 'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output 

Explication

Cette explication est basée sur une suggestion de modification d’un utilisateur anonyme. Merci à qui que ce soit!

Basé sur l’ordre des opérations, cela fonctionne dans l’ordre suivant:

  1. L’opérateur crée un tableau de valeurs à tester.
  2. L’opérateur -ne filtre tous les éléments du tableau qui correspondent à la valeur spécifiée – dans ce cas, null. Le résultat est un tableau de valeurs non nulles dans le même ordre que le tableau créé à l’étape 1.
  3. [0] est utilisé pour sélectionner le premier élément du tableau filtré.

Simplifier cela:

  1. Créer un tableau de valeurs possibles, dans l’ordre de préférence
  2. Exclure toutes les valeurs nulles du tableau
  3. Prenez le premier élément du tableau résultant

Mises en garde

Contrairement à l’opérateur de coalescence null de C #, chaque expression possible sera évaluée, car la première étape consiste à créer un tableau.

C’est seulement une demi-réponse à la première moitié de la question, donc un quart de réponse si vous voulez, mais il existe une alternative beaucoup plus simple à l’opérateur de coalescence nulle, à condition que la valeur par défaut soit la valeur par défaut :

 ssortingng s = myval ?? ""; 

Peut être écrit en Powershell comme:

 ([ssortingng]myval) 

Ou

 int d = myval ?? 0; 

traduit à Powershell:

 ([int]myval) 

J’ai trouvé le premier de ces éléments utile lors du traitement d’un élément xml qui pourrait ne pas exister et qui, s’il existait, pourrait avoir des espaces blancs indésirables:

 $name = ([ssortingng]$row.td[0]).Trim() 

La conversion en chaîne protège contre la nullité de l’élément et évite tout risque d’échec de Trim() .

Si vous installez le module Powershell Community Extensions, vous pouvez utiliser:

?? est l’alias pour Invoke-NullCoalescing.

 $s = ?? {$myval} {"New Value"} 

?: est l’alias pour Invoke-Ternary.

 $x = ?: {$myval -eq $null} {""} {$otherval} 

$null, $null, 3 | Select -First 1

résultats

3

 function coalesce { Param ([ssortingng[]]$list) #$default = $list[-1] $coalesced = ($list -ne $null) $coalesced[0] } function coalesce_empty { #COALESCE for empty_ssortingngs Param ([ssortingng[]]$list) #$default = $list[-1] $coalesced = (($list -ne $null) -ne '')[0] $coalesced[0] } 

Souvent, je trouve que je dois aussi traiter les chaînes vides comme nulles lorsque vous utilisez la fusion. J’ai fini par écrire une fonction pour cela, qui utilise la solution de Zenexer pour la coalescence pour la simple coalescence nulle, puis j’ai utilisé Keith Hill pour une vérification nulle ou vide et ajouté cela comme indicateur pour que ma fonction fasse les deux.

Un des avantages de cette fonction est qu’elle gère également tous les éléments null (ou vides), sans lancer une exception. Il peut également être utilisé pour de nombreuses variables d’entrée arbitraires, grâce à la façon dont PowerShell gère les entrées de tableau.

 function Coalesce([ssortingng[]] $SsortingngsToLookThrough, [switch]$EmptySsortingngAsNull) { if ($EmptySsortingngAsNull.IsPresent) { return ($SsortingngsToLookThrough | Where-Object { $_ } | Select-Object -first 1) } else { return (($SsortingngsToLookThrough -ne $null) | Select-Object -first 1) } } 

Cela produit les résultats de test suivants:

 Null coallesce tests: 1 (w/o flag) - empty/null/'end' : 1 (with flag) - empty/null/'end' : end 2 (w/o flag) - empty/null : 2 (with flag) - empty/null : 3 (w/o flag) - empty/null/$false/'end' : 3 (with flag) - empty/null/$false/'end' : False 4 (w/o flag) - empty/null/"$false"/'end' : 4 (with flag) - empty/null/"$false"/'end' : False 5 (w/o flag) - empty/'false'/null/"$false"/'end': 5 (with flag) - empty/'false'/null/"$false"/'end': false 

Code de test:

 Write-Host "Null coalesce tests:" Write-Host "1 (w/o flag) - empty/null/'end' :" (Coalesce '', $null, 'end') Write-Host "1 (with flag) - empty/null/'end' :" (Coalesce '', $null, 'end' -EmptySsortingngAsNull) Write-Host "2 (w/o flag) - empty/null :" (Coalesce('', $null)) Write-Host "2 (with flag) - empty/null :" (Coalesce('', $null) -EmptySsortingngAsNull) Write-Host "3 (w/o flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end') Write-Host "3 (with flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end' -EmptySsortingngAsNull) Write-Host "4 (w/o flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end') Write-Host "4 (with flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end' -EmptySsortingngAsNull) Write-Host "5 (w/o flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end') Write-Host "5 (with flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end' -EmptySsortingngAsNull)