>我有一个带有如下参数的函数:
function foo {
Param(
[Parameter(Mandatory)]
[string]$foo,
[Parameter(Mandatory)]
[hashtable]$bar
)
}
如果我这样称呼它,一切正常:
foo -foo "abc" -bar @{"a"="b"}
但是,如果我只调用foo
并且PowerShell要求我为强制参数指定值,则它不会接受我的哈希表。
PS C:Usersabc> foo
cmdlet foo at command pipeline position 1
Supply values for the following parameters:
foo: "abc"
bar: @{"a"="b"}
Cannot convert the "@{"a"="b"}" value of type "System.String" to type "System.Collections.Hashtable".
为什么PowerShell不采用我指定的值?
我也尝试以不同的方式编写它,如@{a=b}
、"a"="b"
、@{a=b;}
、@{"a"="b";}
等。
如果将参数标记为Mandatory
,并且在调用时未为其指定值(参数(,PowerShell 会自动提示你输入值。
不幸的是,这种缺少强制参数值的自动提示机制被破坏了(它从未起作用,从 PowerShell v7 开始仍然不起作用(:
-
当前无法以交互方式为以下任何类型提供值:
[hashtable]
、[scriptblock]
、[bool]
、[switch]
(后两者作为强制性参数并不常见(——它们的文字形式@{ ... }
、{ ... }
和$true
/$false
根本无法识别。- 也没有办法以交互方式指定
$null
。
-
此外,自动提示在起作用时不方便(没有选项卡完成,没有对无效输入进行重新提示(,因此目前用处不大。
-
这些问题正在 GitHub 问题 #4068 中讨论。
鉴于上述情况,最好完全绕过自动提示,而是在未提供值时抛出错误:
function foo {
Param(
# Use a default value that throws an error.
[string] $foo = $(Throw "Please pass a value for -foo."),
# Use a default value that throws an error.
[hashtable] $bar = $(Throw "Please pass a value for -bar.")
)
}
请注意,不得使用[Parameter(Mandatory)]
,因为尽管存在默认值,但这仍会触发自动提示。
- 不幸的是,不可避免的后果是,检查命令的语法图不会指示该参数是必需的。
Read-Host(发生这种情况时自动调用(始终返回字符串。如果你想像这样接受哈希表输入,你需要处理输入。我会做这样的事情:
if ($foo -is [system.Collections.hashtable]) {
//proceed
} else if ($foo -is [system.array]) {
Foreach ($fooItem in $foo) {
$myhash.add($key, $fooItem)
}
} else if ($foo -is [system.string]) {
$fooItem = $foo.split(,)
...
} else {
//error
}