为什么我的强制性哈希表参数不采用我的值



>我有一个带有如下参数的函数:

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
}

最新更新