Powershell 中的空条件?

Null Conditional in Powershell?

C# 和其他语言通常有空条件 ?.

A?.B?.Do($C);

当A或B为空时不会出错。 我如何在 powershell 中实现类似的功能,更好的方法是什么:

if ($A) {
  if ($B) {
    $A.B.Do($C);
  }
}

PowerShell 没有 null 条件运算符,但它会默默地忽略 属性 对 null 值表达式的引用,因此您只需 "skip" 到链尾的方法调用:

if($null -ne $A.B){
  $A.B.Do($C)
}

在任何深度工作:

if($null -ne ($target = $A.B.C.D.E)){
    $target.Do($C)
}

Powershell 7 Preview 5 具有处理空值的运算符。 https://devblogs.microsoft.com/powershell/powershell-7-preview-5/

$a = $null

$a ?? 'is null' # return $a or string if null
is null

$a ??= 'no longer null'  # assign if null

$a ?? 'is null'
no longer null

编辑:Powershell 7 预览版 6 堆更多新运算符:https://devblogs.microsoft.com/powershell/powershell-7-preview-6/。因为变量名可以有一个“?”在名称中,您必须用花括号将变量名括起来:

${A}?.${B}?.Do($C)

正如 指出的那样,PowerShell 默认情况下 相对于 具有空条件访问行为(空浸泡) ]属性访问[1];例如,$noSuchVar.Prop 安静地 returns $null

显示相关的 null-coalescing 运算符 (??) / 空条件赋值 运算符 (??=)在 PowerShell [Core] v 7.1+ 中可用

但是,直到 PowerShell 7.0:

  • 没有方法可以空条件地忽略方法调用$noSuchVar.Foo()总是失败。

  • 类似地,有 no 方法来有条件地忽略(数组)indexing: $noSuchVar[0] 总是失败。

  • 如果您选择使用 Set-StrictMode 更严格的行为,甚至 属性-access null-soaking 也不再是一个选项:使用 Set-StrictMode -Version 1 或更高版本, $noSuchVar.Prop 导致错误。

PowerShell [Core] 7.1+ 中,null-conditional(null-soaking) 运算符可用:

新运算符:

  • 原则上与 C# 具有 相同的形式?. ?[...]

  • 但是 - 从 v7.1 开始 - 需要 {...}[ 中包含变量名=109=]

也就是说,你目前不能只使用$noSuchVar?.Foo()$A?.B$A?[1],你必须使用
${noSuchVar}?.Foo()${A}?.B${A}?[1]

这种繁琐语法的原因是存在向后兼容性问题,因为?是变量名中的合法字符,所以假设现有代码如$var? = @{ one = 1}; $var?.one 可以在不使用 {...} 来消除变量名称歧义的情况下中断;实际上,这种用法是 vanishingly rare.

如果您认为不阻碍新语法比可能破坏变量名以 ? 结尾的脚本更重要,请在 this GitHub issue[=109 发表您的意见=].


[1] PowerShell 的默认行为甚至提供存在-条件属性 访问;例如,$someObject.NoSuchProp 安静地 returns $null.