[英]Passing null to a mandatory parameter to a function
實際上我的問題歸結為:
我不能有一個帶有強制參數的函數,並將$ 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中找到這樣做的方法。
我該怎么做?
您應該能夠為[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.要繞過它,您有一個幾個選項:
正如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]
返回值為0
的[int]
對象 $null
傳遞給[bool]
返回值為False
的[bool]
對象 $null
傳遞給[wmi]
返回......沒有。 它根本不會創建一個對象。 這可以通過執行([wmi] $null).GetType()
來確認,它會拋出錯誤 $null
傳遞給[string]
返回一個值為''
(空字符串)的[string]
對象。 這可以通過執行([string] $null).GetType()
和([string] $null).Length
([string] $null).GetType()
來確認。 那么,如果我們有一個非強制性[int]
參數的函數,如果我們不傳遞該參數,它將具有什么值? 讓我們檢查:
Function Foo {
Param (
[int] $Bar
)
Write-Host $Bar
}
Foo
> 0
顯然,如果它是[bool]
該值為False
,如果它是[string]
該值將為''
因此,當我們有大多數標准類型的強制參數並且我們將其賦值為$null
,我們不會獲得$null
,而是獲得該類型的“默認值”。
例:
Function Foo {
Param (
[Parameter(Mandatory = $true)][int] $Bar
)
Write-Host $Bar
}
Foo -Bar $null
> 0
注意那里根本沒有[AllowNull()]
,但它仍然返回0
。
[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
}
這允許將“true” $null
傳遞給int,顯然在調用Write-Host
它會將$null
轉換為字符串,這意味着我們最終會再次使用''
,所以它仍會輸出一些東西,但它是一個“true” $null
被傳遞。
像[wmi]
(或.NET類)這樣的可空類型更容易,因為它們從一開始就已經可以為空,所以它們不需要可以為空,但仍然需要[AllowNull()]
。
至於使一個[string]
真正可以為空,那個仍然可以逃避我,就像試圖做的那樣:
[System.Nullable[string]]
返回錯誤。 很可能是因為system.string
已經可以為空了,盡管PowerShell似乎沒有這樣看。
編輯
我只是注意到了
[bool] $null
被強迫進入False
,做......
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]
。
我想你錯過了“,”來分離參數。
Param (
[string]$ObjectName,
[int]$ObjectId,
[wmi]$Object
)
首先,添加AllowNull
屬性:
Function Foo
{
Param
(
[Parameter(Mandatory = $true)][AllowNull()][string] $Bar
)
Write-Host $Bar
}
然后,當您調用該函數時,請注意當用於[string]
時$null
變為空字符串,而不是空引用。 因此(自PowerShell 3(2012))使用[NullString]::Value
如下所示:
Foo -Bar ([NullString]::Value)
請參閱System.Management.Automation.Language.NullString
類的文檔 。
編輯:從調用站點,這似乎工作,但是當您到達函數內的Write-Host
cmdlet時, $Bar
將再次變為空字符串。 見下面的評論。 我們必須得出結論,PowerShell堅持字符串必須是這樣的。 請注意, NullString
(在其他情況下對我有用)在其文檔中僅承諾在將null “傳遞給.NET方法”時會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.