2010-03-05 22 views
6

Lavorando a uno script PowerShell avevo diversi punti in cui volevo A a meno che non fosse null, altrimenti B. Essenzialmente il ?? operatore in C#. Ho finito per scrivere la funzione mostrata di seguito, ma non posso fare a meno di pensare che ci sia un modo integrato per farlo.Valori predefiniti per valori nulli

C'è un modo migliore, integrato?

function Get-ValueOrDefault() 
{ 
    foreach ($value in $args) 
    { 
     if ($value -ne $null) { return $value } 
    } 
} 

penso che questo funziona meglio:

function Get-ValueOrDefault() { $args | select -first 1 } 
+1

Un problema con la funzione è che se si passa booleani avrai risultati inaspettati. Dovrebbe invece confrontare $ valore -eq $ null. – Josh

+0

Buon punto, Josh. – OldFart

+0

In una domanda simile http://stackoverflow.com/questions/10623907/null-coalescing-in-powershell è stato suggerito ($ value, 'default' -ne $ null) [0] nella risposta http: // stackoverflow. com/a/17647824/52277 –

risposta

5

Questo è ciò che forniamo nel PowerShell Community Extensions:

<# 
.SYNOPSIS 
    Similar to the C# ?? operator e.g. name = value ?? String.Empty 
.DESCRIPTION 
    Similar to the C# ?? operator e.g. name = value ?? String.Empty; 
    where value would be a Nullable&lt;T&gt; in C#. Even though PowerShell 
    doesn't support nullables yet we can approximate this behavior. 
    In the example below, $LogDir will be assigned the value of $env:LogDir 
    if it exists and it's not null, otherwise it get's assigned the 
    result of the second script block (C:\Windows\System32\LogFiles). 
    This behavior is also analogous to Korn shell assignments of this form: 
    LogDir = ${$LogDir:-$WinDir/System32/LogFiles} 
.PARAMETER PrimaryExpr 
    The condition that determines whether the TrueBlock scriptblock is used or the FalseBlock 
    is used. 
.PARAMETER AlternateExpr 
    This block gets evaluated and its contents are returned from the function if the Conditon 
    scriptblock evaluates to $true. 
.EXAMPLE 
    C:\PS> $LogDir = ?? {$env:LogDir} {"$env:windir\System32\LogFiles"} 
    $LogDir is set to the value of $env:LogDir unless it doesn't exist, in which case it 
    will then default to "$env:windir\System32\LogFiles". 
#> 
filter Invoke-NullCoalescing { 
    param([scriptblock]$PrimaryExpr = $(throw "Parameter '-primaryExpr' (position 1) required"), 
      [scriptblock]$AlternateExpr = $(throw "Parameter '-alternateExpr' (position 2) required")) 

    if ($primaryExpr -ne $null) { 
     $result = &$primaryExpr 
     if ($result -ne $null -and "$result" -ne '') { 
      $result 
     } 
     else { 
      &$alternateExpr 
     } 
    } 
    else { 
     &$alternateExpr 
    } 
} 

New-Alias ?? Invoke-NullCoalescing 

PS> ?? {$xyzzy} {"empty"} 
empty 

PS> ?? {$psversiontable} {"empty"} 

Name       Value 
----       ----- 
CLRVersion      2.0.50727.4927 
BuildVersion     6.1.7600.16385 
PSVersion      2.0 
WSManStackVersion    2.0 
PSCompatibleVersions   {1.0, 2.0} 
SerializationVersion   1.1.0.1 
PSRemotingProtocolVersion  2.1 
+0

C'è qualcosa che PSCX non fornisce? ;) – stej

+0

Oh sì, c'è spazio per nuove cose. :-) –

+0

Non accetto questa risposta perché stavo cercando qualcosa che non richieda la definizione di nuove funzioni, sia visivamente piacevole e il cui scopo è abbastanza ovvio per chi legge la sceneggiatura. – OldFart