PowerShell字符串默认参数值不按预期工作

37
#Requires -Version 2.0

[CmdletBinding()]
Param(
  [Parameter()] [string] $MyParam = $null
)

if($MyParam -eq $null) {
  Write-Host 'works'
} else {
  Write-Host 'does not work'
}

输出 "does not work" => 看起来字符串会被隐式地从 null 转换成空字符串?为什么?如何测试一个字符串是空还是真正的 $null 呢?这应该是两个不同的值!

5个回答

40

好的,找到答案在https://www.codykonior.com/2013/10/17/checking-for-null-in-powershell/

��设:

Param(
  [string] $stringParam = $null
)

参数未指定(正在使用默认值):

# will NOT work
if ($null -eq $stringParam)
{
}

# WILL work:
if ($stringParam -eq "" -and $stringParam -eq [String]::Empty)
{
}

或者,您可以指定一个特殊的 null 类型:

Param(
  [string] $stringParam = [System.Management.Automation.Language.NullString]::Value
)

在这种情况下,$null -eq $stringParam将按预期工作。

奇怪!


2
请注意,在PowerShell中,您应该使用if ($null -eq $value)而不是if ($value -eq $null)。 PowerShell脚本分析器模块也会发出此警告。请参见https://www.spcaf.com/blog/powershell-null-comparison/。 - oɔɯǝɹ
更好的方法是 if ([String::IsNullOrEmpty($stringParam)]),这会稍微改变一下行为(我认为是变得更好了),但读起来很流畅,并且消除了顺序问题。无论如何,谢谢,这对我帮助很大。 - Lee Richardson

14

如果您想允许字符串参数的 $null,则需要使用 AllowNull 属性:

[CmdletBinding()]
Param (
    [Parameter()] 
    [AllowNull()]
    [string] $MyParam
)

请注意,您应该在比较的左侧使用$null:

if ($null -eq $MyParam)

如果您希望它能够可预测地工作

3

看到很多与 [String]::Empty 进行比较的情况,您可以使用 [String]::IsNullOrWhiteSpace 或 [String]::IsNullOrEmpty 静态方法,如下所示:

param(
    [string]$parameter = $null
)

# we know this is false
($null -eq $parameter)

[String]::IsNullOrWhiteSpace($parameter)
[String]::IsNullOrEmpty($parameter)
('' -eq $parameter)
("" -eq $parameter)

得到:

PS C:\...> .\foo.ps1
False
True
True
True
True

这个答案实际上没有回答问题中的任何评论(即,当将 $null 分配给 [string] 参数时的行为解释)。 - Mathias R. Jessen
我以为我已经回答了这个问题:“如何测试一个字符串是空的还是真正的$null?” - Scottley

3

如果您希望参数的值为 $null,请不要声明其类型:

Param(
    $stringParam
)

当声明类型时,其他解决方案都对我没用。


我想在处理字符串时切换到JavaScript风格的声明和比较(不幸的是)。这篇文章的其余部分似乎反映了PowerShell的负担。 - dudeNumber4

1

因此,对于类型为[string]的参数,默认值似乎为$null,无论出于何种原因,默认值都将为空字符串。

选项1

if ($stringParam) { ... }

选项2
if ($stringParam -eq "") { ... }

选项3
if ($stringParam -eq [String]::Empty) { ... }

1
对于未被赋值的变量,我更喜欢使用 If (-not $stringParam) { ... } - Anton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接