将 null 传递给函数的强制参数 [英] Passing null to a mandatory parameter to a function

查看:49
本文介绍了将 null 传递给函数的强制参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实际上我的问题归结为:

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 value 0
  • Passing $null to a [bool] returns a [bool] object with value False
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆