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

PowerShell字符串默认参数值未按预期工作,powershell,powershell-4.0,Powershell,Powershell 4.0,输出“不工作”=>字符串是否隐式地从空字符串转换为空字符串?为什么?如何测试字符串是空的还是真正的$null?这应该是两个不同的值 好的,找到了答案@ 假设: #Requires -Version 2.0 [CmdletBinding()] Param( [Parameter()] [string] $MyParam = $null ) if($MyParam -eq $null) { Write-Host 'works' } else { Write-Host 'does no

输出“不工作”=>字符串是否隐式地从空字符串转换为空字符串?为什么?如何测试字符串是空的还是真正的$null?这应该是两个不同的值

好的,找到了答案@

假设:

#Requires -Version 2.0

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

if($MyParam -eq $null) {
  Write-Host 'works'
} else {
  Write-Host 'does not work'
}
并且未指定参数(使用默认值):

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

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

# WILL work:
if ($stringParam -eq "" -and $stringParam -eq [String]::Empty)
{
}
在这种情况下,
$null-eq$stringParam
将按预期工作


奇怪

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

选择1

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

if ($stringParam) { ... }
选择3

if ($stringParam -eq "") { ... }

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

if ($stringParam -eq [String]::Empty) { ... }
请注意:


如果您想让它以可预测的方式工作

看到许多与[String]::Empty的相等比较,可以使用[String]::IsNullOrWhiteSpace或[String]::IsNullOrEmpty静态方法,如下所示:

if ($null -eq $MyParam)
这将产生:

param(
    [string]$parameter = $null
)

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

[String]::IsNullOrWhiteSpace($parameter)
[String]::IsNullOrEmpty($parameter)
('' -eq $parameter)
("" -eq $parameter)
如果希望保留$null值,请不要声明参数的类型:

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

(声明类型时,没有其他解决方案对我有效。)

对于未分配,我更喜欢
If(-not$stringParam){…}
请注意,在PowerShell中,您应该真正使用
If($null-eq$value)
而不是
If($value-eq$null)
。PowerShell脚本分析器模块也会对此发出警告。请参见或更好地参见
if([String::IsNullOrEmpty($stringParam)])
,它稍微改变了行为(为了更好地理解imo),但读起来很好,并且消除了顺序问题。不管怎样,谢谢,这对我帮助很大。这个答案并没有真正解决问题中的任何问题(即,将
$null
赋值给
[string]
参数时的行为解释),我以为我回答了这个问题:“以及如何测试字符串是空的还是真的$null?”当涉及到字符串时,切换到javascript风格的声明和比较(不幸的是)。这篇文章的其余部分似乎都反映了powershell的包袱。
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
Param(
    $stringParam
)