将 null 传递给函数的强制参数 [英] Passing null to a mandatory parameter to a function
问题描述
实际上我的问题归结为:
Effectively my problem comes down to this:
我不能有一个带有强制参数的函数并将 $null 传递给该参数:
I can't have a function with a mandatory parameter and pass $null to that parameter:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][string] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
这将返回 foo : 无法将参数绑定到参数Bar",因为它是一个空字符串.
同样,将其设为数组也会失败:
Likewise, making it an array also fails:
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 中找不到这样做的方法.
In programming terms it is entirely possible to have a function that accepts a mandatory nullable parameter, but I can't find a way of doing that in PowerShell.
我该怎么做?
推荐答案
如 Rohn Edwards 的回答中所述,[AllowNull()]
和/或 [AllowEmptyString()]
是解决方案的一部分,但需要考虑一些事项.
As mentioned in Rohn Edwards's answer, [AllowNull()]
and/or [AllowEmptyString()]
are part of the solution, but a few things need to be taken into account.
尽管题中给出的例子是类型字符串,但题主的问题是如何将null传递给强制参数,没有提到类型,所以我们需要稍微扩展一下答案.
Even though the example given in the question is with a type string, the question on the title is how to pass null to a mandatory parameter, without a mention of type, so we need to expand the answer slightly.
首先让我们看看 PowerShell 如何处理将 $null 分配给某些类型:
First let us look at how PowerShell handles assigning $null to certain types:
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]
对象,其值为0
立> - 将
$null
传递给[bool]
会返回一个[bool]
对象,其值为False
立> - 将
$null
传递给[wmi]
返回......什么也没有.它根本不创建对象.这可以通过执行([wmi] $null).GetType()
来确认,这会引发错误 - 将
$null
传递给[string]
会返回一个[string]
对象,其值为''
(空字符串).这可以通过执行([string] $null).GetType()
和([string] $null).Length
来确认
- Passing
$null
to an[int]
returns an[int]
object with value0
- Passing
$null
to a[bool]
returns a[bool]
object with valueFalse
- Passing
$null
to a[wmi]
returns ... nothing. It does not create an object at all. This can be confirmed by doing([wmi] $null).GetType()
, which throws an error - Passing
$null
to a[string]
returns a[string]
object with value''
(empty string). This can be confirmed by doing([string] $null).GetType()
and([string] $null).Length
那么,如果我们有一个带有非强制性 [int]
参数的函数,如果我们不传递该参数,它会有什么值?让我们检查一下:
So, if we have a function with a non-mandatory [int]
parameter what value will it have if we don't pass that parameter? Let's check:
Function Foo {
Param (
[int] $Bar
)
Write-Host $Bar
}
Foo
> 0
显然,如果它是 [bool]
的值是 False
,如果它是 [string]
的值将是 <代码>''
Obviously if it was a [bool]
the value with be False
and if it was a [string]
the value would be ''
所以当我们有一个大多数标准类型的强制参数并且我们给它赋值$null
时,我们没有得到$null
,但是而是该类型的默认值".
So when we have a mandatory parameter of most standard types and we assign it $null
, we are not getting $null
, but rather the "default value" for that type.
示例:
Function Foo {
Param (
[Parameter(Mandatory = $true)][int] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
> 0
注意那里根本没有[AllowNull()]
,但它仍然返回一个0
.
Notice there is no [AllowNull()]
at all there, yet it still returns a 0
.
A [string]
略有不同,因为它不允许强制参数上有空字符串,这就是问题中的示例失败的原因.[AllowNull()]
也没有修复它,因为空字符串与 $null
不同,所以我们需要使用 [AllowEmptyString()]代码>.其他任何事情都会失败.
A [string]
is slightly different, in the sense that it doesn't allow empty strings on a mandatory parameter, which is why the example in the question fails. [AllowNull()]
doesn't fix it either, as an empty string is not the same as $null
and so we need to use [AllowEmptyString()]
. Anything else will fail.
那么,[AllowNull()]
在哪里起作用,以及如何将真实的"$null
传递给 int、bool、wmi 等?
So, where does [AllowNull()]
come in play, and how to pass a "real" $null
to an int, bool, wmi, etc?
int 和 bool 都不是可空类型,因此为了向它们传递真正的"$null
,您需要使它们可以为空:
Neither int nor bool are nullable types, so in order to pass a "real" $null
to them you need to make them nullable:
Function Foo {
Param (
[Parameter(Mandatory = $true)][AllowNull()][System.Nullable[int]] $Bar
)
Write-Host $Bar
}
这允许将真实"$null
传递给 int,显然在调用 Write-Host
时它会转换 $null
到一个字符串,这意味着我们再次以 ''
结束,所以它仍然会输出一些东西,但它是一个真实"的 $null
被传递.
This allows a "true" $null
to be passed to an int, obviously when calling Write-Host
it converts the $null
to a string meaning we end up with an ''
again, so it will still output something, but it is a "true" $null
being passed.
像 [wmi]
(或 .NET 类)这样的可空类型更容易,因为它们从一开始就可以为空,因此不需要将它们设为可空,但仍然需要 [AllowNull()]
.
Nullable types like [wmi]
(or a .NET class) are easier as they are already nullable from the start, so they don't need to be made nullable, but still require [AllowNull()]
.
至于使 [string]
真正可以为空,我仍然无法做到:
As for making a [string]
truly nullable, that one still eludes me, as trying to do:
[System.Nullable[string]]
返回错误.很可能是因为 system.string
已经可以为空了,尽管 PowerShell 似乎并不这么认为.
Returns an error. Very likely because a system.string
is nullable already, though PowerShell doesn't seem to see it that way.
编辑
我刚刚注意到,虽然
[bool] $null
被强制转换为 False
,做...
gets coerced into False
, doing...
Function Foo {
Param (
[bool] $Bar
)
$Bar
}
Foo -Bar $null
抛出以下错误:
Foo : Cannot process argument transformation on parameter 'Bar'. Cannot convert value "" to type "System.Boolean".
这很奇怪,因为在上面的函数中使用 [switch]
而不是 [bool]
更有效.
This is quite bizarre, even more so because using [switch]
in the function above instead of [bool]
works.
这篇关于将 null 传递给函数的强制参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!