将null传递给函数的必需参数

时间:2014-08-23 08:01:04

标签: powershell

实际上我的问题归结为:

我不能使用强制参数的函数,并将$ 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中找不到这样做的方法。

我该怎么做?

4 个答案:

答案 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。你有几个选择:

  • 删除参数类型约束。您可以在代码中检查$ null,然后转换为您想要的类型。
  • 使用System.Nullable(请参阅其他答案)。这仅适用于值类型。
  • 重新考虑函数设计,以便您没有必须允许null的必需参数。

答案 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方法”时才有用。