实际上我的问题归结为:
我不能使用强制参数的函数,并将$ null传递给该参数:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][string] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
这会返回foo : Cannot bind argument to parameter 'Bar' because it is an empty string.
同样,使它成为一个数组也失败了:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][string[]] $Bar
)
Write-Host $Bar
}
Foo -Bar 1, 2
> 1 2
Foo -Bar 1, 2, $null
> foo : Cannot bind argument to parameter 'Bar' because it is an empty string.
在编程术语中,完全可以使用一个接受强制可为空参数的函数,但我在PowerShell中找不到这样做的方法。
我该怎么做?
答案 0 :(得分:27)
您应该能够为[string]参数使用[AllowEmptyString()]参数和/或为其他类型使用[AllowNull()]参数属性。我已经从您的示例中为函数添加了[AllowEmptyString()]属性:
Function Foo {
Param
(
[Parameter(Mandatory = $true)]
[AllowEmptyString()] <#-- Add this #>
[string] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
有关详细信息,请查看about_Functions_Advanced_Parameters帮助主题。
请注意,PowerShell会在参数绑定期间将$ null值强制转换为某些类型的实例,例如,[string] $null
变为空字符串,[int] $null
变为0。你有几个选择:
答案 1 :(得分:20)
正如Rohn Edwards的回答所述,[AllowNull()]
和/或[AllowEmptyString()]
是解决方案的一部分,但需要考虑一些事项。
尽管问题中给出的示例是带有类型字符串,但标题上的问题是如何将null传递给强制参数,而不提及类型,因此我们需要稍微扩展答案。
首先让我们看看PowerShell如何处理为某些类型分配$ null:
PS C:\> [int] $null
0
PS C:\> [bool] $null
False
PS C:\> [wmi] $null
PS C:\>
PS C:\> [string] $null
PS C:\>
分析结果:
$null
传递给[int]
会返回值为[int]
的{{1}}个对象0
传递给$null
会返回值为[bool]
的{{1}}个对象[bool]
传递给False
会返回......没有。它根本不会创建一个对象。这可以通过执行$null
来确认,这会引发错误[wmi]
传递给([wmi] $null).GetType()
会返回值为$null
的{{1}}对象(空字符串)。这可以通过[string]
和[string]
因此,如果我们有一个带有非强制性''
参数的函数,如果我们不传递该参数,它会有什么价值?我们来看看:
([string] $null).GetType()
显然,如果([string] $null).Length
值是[int]
,如果它是Function Foo {
Param (
[int] $Bar
)
Write-Host $Bar
}
Foo
> 0
,则值为[bool]
因此,当我们有大多数标准类型的强制参数并且我们为其分配False
时,我们没有得到[string]
,而是&#34;默认值& #34;对于那种类型。
示例:
''
请注意,根本没有$null
,但仍然会返回$null
。
Function Foo {
Param (
[Parameter(Mandatory = $true)][int] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
> 0
略有不同,因为它不允许在强制参数上使用空字符串,这就是问题中的示例失败的原因。 [AllowNull()]
也无法修复,因为空字符串与0
不同,因此我们需要使用[string]
。其他任何事情都会失败。
那么,[AllowNull()]
在哪里发挥作用,以及如何传递&#34;真实&#34; $null
到int,bool,wmi等?
int和bool都不是可空类型,所以为了传递一个真实的&#34; [AllowEmptyString()]
他们需要让他们可以为空:
[AllowNull()]
这允许&#34; true&#34;要将$null
传递给int,显然在调用$null
时会将Function Foo {
Param (
[Parameter(Mandatory = $true)][AllowNull()][System.Nullable[int]] $Bar
)
Write-Host $Bar
}
转换为字符串,这意味着我们最终会再次使用$null
,因此它仍会输出某些内容,但这是一个真实的&#34; Write-Host
正在通过。
像$null
(或.NET类)这样的可空类型更容易,因为它们从一开始就已经可以为空,因此它们不需要被设为可空,但仍然需要''
至于让一个$null
真正可以为空,那个人仍然可以逃避我的努力:
[wmi]
返回错误。很可能是因为[AllowNull()]
已经可以为空了,但PowerShell似乎并没有这样看。
修改强>
我注意到了,而
[string]
被强制进入[System.Nullable[string]]
,做......
system.string
引发以下错误:
[bool] $null
这非常奇怪,更是如此,因为在上面的函数中使用False
而不是Function Foo {
Param (
[bool] $Bar
)
$Bar
}
Foo -Bar $null
。
答案 2 :(得分:1)
我认为你错过了“,”来分隔参数。
Param (
[string]$ObjectName,
[int]$ObjectId,
[wmi]$Object
)
答案 3 :(得分:1)
首先,添加AllowNull
属性:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][AllowNull()][string] $Bar
)
Write-Host $Bar
}
然后,当您调用该函数时,请注意$null
在用于[string]
时变为空字符串,而不是空引用。因此(自PowerShell 3(2012)开始)使用[NullString]::Value
,如下所示:
Foo -Bar ([NullString]::Value)
请参阅CLng
。
编辑:在调用网站上显示 ,但是当您到达函数中的Write-Host
cmdlet时,$Bar
将再次变为空字符串。见下面的评论。我们必须得出结论,PowerShell坚持字符串必须是这样的。请注意,NullString
(在其他情况下对我有用)仅在将“传递给.NET方法”时才有用。。