从scrath重写的问题使其更具可读性.
实际上我的问题归结为:
我不能有一个带有强制参数的函数,并将$ null传递给该参数:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][string] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
Run Code Online (Sandbox Code Playgroud)
这回来了 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.
Run Code Online (Sandbox Code Playgroud)
它编程术语完全有可能有一个接受强制可为空参数的函数,但我找不到在PowerShell中这样做的方法.
怎么做?
Roh*_*rds 29
您应该能够为[string]参数使用[AllowEmptyString()]参数属性和/或为其他类型使用[AllowNull()]参数属性.我已经从您的示例中为函数添加了[AllowEmptyString()]属性:
Function Foo {
Param
(
[Parameter(Mandatory = $true)]
[AllowEmptyString()] <#-- Add this #>
[string] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请查看about_Functions_Advanced_Parameters帮助主题.
请注意,PowerShell会在参数绑定期间将$ null值强制转换为某些类型的实例,例如,[string] $null变为空字符串并[int] $null变为0.要解决此问题,您可以选择以下几种方法:
cog*_*el0 21
正如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:\>
Run Code Online (Sandbox Code Playgroud)
分析结果:
$null给[int]返回[int]具有值的对象0$null给一个[bool]返回一个[bool]有价值的对象False$null的[wmi]回报...什么都没有.它根本不会创建一个对象.这可以通过执行来确认([wmi] $null).GetType(),这会引发错误$null给一个[string]返回一个[string]带有值的对象''(空字符串).这可以通过做([string] $null).GetType()和确认([string] $null).Length那么,如果我们有一个带有非强制[int]参数的函数,如果我们不传递该参数,它将具有什么值?让我们检查:
Function Foo {
Param (
[int] $Bar
)
Write-Host $Bar
}
Foo
> 0
Run Code Online (Sandbox Code Playgroud)
显然,如果它是a [bool]的值,False如果它是一个[string]值将是''
因此,当我们有大多数标准类型的强制参数并且我们分配它时$null,我们没有得到$null,而是该类型的"默认值".
例:
Function Foo {
Param (
[Parameter(Mandatory = $true)][int] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
> 0
Run Code Online (Sandbox Code Playgroud)
注意那里根本没有[AllowNull()],但它仍然返回一个0.
A [string]在某种意义上略有不同,因为它不允许在强制参数上使用空字符串,这就是问题中的示例失败的原因.[AllowNull()]也没有解决它,因为空字符串不一样$null,所以我们需要使用[AllowEmptyString()].其他任何事情都会失败.
那么,在哪里[AllowNull()]发挥作用,以及如何将"真实"传递$null给int,bool,wmi等?
int和bool都不是可空类型,所以为了向它们传递"真实" $null,你需要使它们可以为空:
Function Foo {
Param (
[Parameter(Mandatory = $true)][AllowNull()][System.Nullable[int]] $Bar
)
Write-Host $Bar
}
Run Code Online (Sandbox Code Playgroud)
这允许将"true" $null传递给int,显然在调用Write-Host它时将其转换$null为字符串意味着我们最终''会再次输出,因此它仍然会输出一些内容,但它是一个"true" $null传递.
像[wmi](或.NET类)这样的可空类型更容易,因为它们从一开始就已经可以为空,所以它们不需要可以为空,但仍然需要[AllowNull()].
至于制作一个[string]真正可以为空的东西,那个仍然无法逃避我的努力:
[System.Nullable[string]]
Run Code Online (Sandbox Code Playgroud)
返回错误.很可能因为a system.string已经可以为空了,尽管PowerShell似乎并没有这样看待它.
编辑
我只是注意到了
[bool] $null
Run Code Online (Sandbox Code Playgroud)
被胁迫False,做......
Function Foo {
Param (
[bool] $Bar
)
$Bar
}
Foo -Bar $null
Run Code Online (Sandbox Code Playgroud)
抛出以下错误:
Foo : Cannot process argument transformation on parameter 'Bar'. Cannot convert value "" to type "System.Boolean".
Run Code Online (Sandbox Code Playgroud)
这是非常离奇的,更是如此,因为[switch]在上面的函数中使用而不是[bool]工作.
首先,添加一个AllowNull属性:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][AllowNull()][string] $Bar
)
Write-Host $Bar
}
Run Code Online (Sandbox Code Playgroud)
然后,当您调用该函数时,请注意,$null当使用 for 时,它[string]会变成空字符串,而不是空引用。因此(自 PowerShell 3 (2012) 起)使用[NullString]::Value如下:
Foo -Bar ([NullString]::Value)
Run Code Online (Sandbox Code Playgroud)
请参阅class的文档System.Management.Automation.Language.NullString。
编辑:从调用站点来看,这似乎有效,但一旦您到达Write-Host函数内的 cmdlet,$Bar它将再次变成空字符串。请参阅下面的评论。我们必须得出结论,PowerShell 坚持字符串必须是这样的。请注意NullString(这在其他情况下对我有用)在其文档中仅承诺在将 null “传递到 .NET 方法”时有用。
| 归档时间: |
|
| 查看次数: |
32318 次 |
| 最近记录: |