8 ответов:
нет необходимости в расширениях сообщества Powershell, вы можете использовать стандартные операторы Powershell if в качестве выражения:
variable = if (condition) { expr1 } else { expr2 }Итак, для замены вашего первого выражения:
var s = myval ?? "new value";становится одним из следующих (в зависимости от предпочтений):
$s = if ($myval -eq $null) { "new value" } else { $myval } $s = if ($myval -ne $null) { $myval } else { "new value" }или в зависимости от того, что $myval может содержать вы могли бы использовать:
$s = if ($myval) { $myval } else { "new value" }и второе выражение сопоставляется в аналогичном образом:
var x = myval == null ? "" : otherval;становится
$x = if ($myval -eq $null) { "" } else { $otherval }теперь, чтобы быть справедливым, это не очень быстро, и нет, где почти так же удобно использовать, как формы C#.
вы также можете обернуть его в очень простую функцию, чтобы сделать вещи более читабельным:
function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } } $s = Coalesce $myval "new value"или, возможно, как, IfNull:
function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } } $s = IfNull $myval "new value" $myval $x = IfNull $myval "" $othervalкак вы можете видеть, очень простая функция может дать вам немного свободы синтаксиса.
обновление: один дополнительный вариант рассмотреть в миксе-это более общая функция является истинной:
function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } } $x = IfTrue ($myval -eq $null) "" $othervalзатем объедините это способность Powershell объявлять псевдонимы, которые немного похожи на операторы, вы получите:
New-Alias "??" Coalesce $s = ?? $myval "new value" New-Alias "?:" IfTrue $ans = ?: ($q -eq "meaning of life") 42 $othervalочевидно, что это будет не всем по вкусу, но может быть то, что вы ищете.
да, PowerShell имеет фактический оператор слияния null или, по крайней мере, оператор, способный к такому поведению. Этот оператор
-ne:# Format: # ($a, $b, $c -ne $null)[0] ($null, 'alpha', 1 -ne $null)[0] # Output: alphaон немного более универсален, чем оператор коалесценции null, поскольку он создает массив всех ненулевых элементов:
$items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false $instances = $items -ne $null [string]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() })) # Result: System.String, System.Int32, System.Int32, System.String, System.Object[], System.Boolean, System.Boolean
-eqработает аналогично, что полезно для подсчета нулевых записей:($null, 'a', $null -eq $null).Length # Result: 2но в любом случае, вот типичный случай, чтобы отразить C#'S
??оператор:'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Outputобъяснение
это объяснение основано на предложении редактирования от анонимного пользователя. Спасибо, кто бы вы ни были!
исходя из порядка операций, это работает в следующем порядке:
- The
,оператор создает массив значений для проверки.- The
-neоператор отфильтровывает все элементы из массива, соответствующие указанному значению--в данном случае null. Этот результатом является массив ненулевых значений в том же порядке, что и массив, созданный на Шаге 1.[0]используется для выбора первого элемента отфильтрованный массив.упрощение, что:
- создать массив возможных значений, в предпочтительном порядке
- исключить нулевые значения из массива
- берем первый элемент из результирующего массива
предостережения
в отличие от C#'S null коалесцирующий оператор, каждое возможное выражение будет вычислено, так как первым шагом является создание массива.
это только половина ответа на первую половину вопроса, поэтому ответ на четверть, если хотите, но есть гораздо более простая альтернатива оператору слияния null при условии, что значение по умолчанию, которое вы хотите использовать, на самом деле является значением по умолчанию для типа:
string s = myval ?? "";можно записать в Powershell как:
([string]myval)или
int d = myval ?? 0;переводится в Powershell:
([int]myval)Я нашел первый из них полезным при обработке xml элемент, который может не существовать и который, если он существует, может иметь нежелательные пробелы вокруг него:
$name = ([string]$row.td[0]).Trim()приведение к строке защищает от элемента null и предотвращает любой риск
Trim()сбой.
при установке Модуль Расширений Сообщества Powershell затем вы можете использовать:
?? это псевдоним для Invoke-NullCoalescing.
$s = ?? {$myval} {"New Value"}?: это псевдоним для Invoke-Ternary.
$x = ?: {$myval -eq $null} {""} {$otherval}
function coalesce { Param ([string[]]$list) #$default = $list[-1] $coalesced = ($list -ne $null) $coalesced[0] } function coalesce_empty { #COALESCE for empty_strings Param ([string[]]$list) #$default = $list[-1] $coalesced = (($list -ne $null) -ne '')[0] $coalesced[0] }
часто я нахожу, что мне также нужно рассматривать пустую строку как null при использовании coalesce. Я закончил тем, что написал функцию для этого, которая использует Zenexerдля объединения по той простой нуль сливаются, а затем использовать Кит Хилл ' S для нулевой или пустой проверки, и добавил, что в качестве флага, чтобы моя функция могла делать и то, и другое.
одним из преимуществ этой функции является то, что она также обрабатывает все элементы null (или пустые), не создавая исключения. Он также может использоваться для произвольного множества входных переменных, благодаря тому, как PowerShell обрабатывает входы массива.
function Coalesce([string[]] $StringsToLookThrough, [switch]$EmptyStringAsNull) { if ($EmptyStringAsNull.IsPresent) { return ($StringsToLookThrough | Where-Object { $_ } | Select-Object -first 1) } else { return (($StringsToLookThrough -ne $null) | Select-Object -first 1) } }Это дает следующие результаты теста:
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тестовый код:
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' -EmptyStringAsNull) Write-Host "2 (w/o flag) - empty/null :" (Coalesce('', $null)) Write-Host "2 (with flag) - empty/null :" (Coalesce('', $null) -EmptyStringAsNull) 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' -EmptyStringAsNull) 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' -EmptyStringAsNull) 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' -EmptyStringAsNull)
ближе всего я могу получить это:
$s = $myval |?? "new value"я реализовал оператор коалесценции null для вышеизложенного, как это:
function NullCoalesc { param ( [Parameter(ValueFromPipeline=$true)]$Value, [Parameter(Position=0)]$Default ) if ($Value) { $Value } else { $Default } } Set-Alias -Name "??" -Value NullCoalescThe условный тернарный оператор может быть реализован аналогичным образом.
function ConditionalTernary { param ( [Parameter(ValueFromPipeline=$true)]$Value, [Parameter(Position=0)]$First, [Parameter(Position=1)]$Second ) if ($Value) { $First } else { $Second } } Set-Alias -Name "?:" -Value ConditionalTernaryи используется как:
$x = ($myval -eq $null) |?: "" $otherval
Comments