2010-03-05 17 views
6

Trabajando en un script de Powershell Tenía varios lugares donde quería A a menos que fuera nulo, sino B. ¿Esencialmente el? operador en C#. Terminé escribiendo la función que se muestra a continuación, pero no puedo evitar pensar que hay una forma incorporada de hacerlo.Predeterminado para valores nulos

¿Existe alguna forma mejor incorporada?

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

creo que esto funciona mejor:

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

Uno de los problemas con su función es que si pasa booleanos que tendrá resultados inesperados. En su lugar, debería comparar $ valor -eq $ null. – Josh

+0

Buen punto, Josh. – OldFart

+0

En una pregunta similar http://stackoverflow.com/questions/10623907/null-coalescing-in-powershell se sugirió ($ value, 'default' -ne $ null) [0] en la respuesta http: // stackoverflow. com/a/17647824/52277 –

Respuesta

5

Esto es lo que ofrecemos en el 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

¿Hay algo que PSCX no brinde? ;) – stej

+0

Oh sí, hay espacio para cosas nuevas. :-) –

+0

No acepto esta respuesta porque estaba buscando algo que no requiera definir nuevas funciones, es visualmente agradable y cuyo propósito es bastante obvio para alguien que lee el guión. – OldFart