Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 为什么不';我的函数有公共参数吗?_Function_Powershell_Reflection_Parameters - Fatal编程技术网

Function 为什么不';我的函数有公共参数吗?

Function 为什么不';我的函数有公共参数吗?,function,powershell,reflection,parameters,Function,Powershell,Reflection,Parameters,我试图编写一些代码,要求检查函数元数据,并根据命令参数处理一些其他数据。在这个过程中,我发现了一些我无法理解的非常奇怪的行为 我在psm1脚本模块中有一个函数,它是通过导入相邻的psd1模块清单加载的,该清单将它声明为嵌套模块。我已经明确声明了14个参数。当我Get命令并检查参数时,我可以看到它有23个参数。14个是我的;其余的都是 (我的函数名以Install-开头。不过,我的参数不是以数字结尾。这些只是虚拟占位符,因为我不想使用实名。) 这是意料之中的事。函数应该具有公共参数 但为了测试处理

我试图编写一些代码,要求检查函数元数据,并根据命令参数处理一些其他数据。在这个过程中,我发现了一些我无法理解的非常奇怪的行为

我在psm1脚本模块中有一个函数,它是通过导入相邻的psd1模块清单加载的,该清单将它声明为嵌套模块。我已经明确声明了14个参数。当我
Get命令
并检查
参数
时,我可以看到它有23个参数。14个是我的;其余的都是

(我的函数名以
Install-
开头。不过,我的参数不是以数字结尾。这些只是虚拟占位符,因为我不想使用实名。)

这是意料之中的事。函数应该具有公共参数

但为了测试处理参数的代码,我尝试创建一个测试模块。下面是它的样子:

testfun.psm1

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

function test-noparams() {
    Write-Host 'None'
}

function test-differentnamedparams([string]$hello, [switch]$bye) {
    Write-Host "names that don't conflict with common params"
}
# Define a NON-advanced function - no [CmdletBinding()] or [Parameter()] attributes.
PS> function foo { param([string] $bar) 'hi' }; Get-Help foo

NAME
    foo

SYNTAX
    foo [[-bar] <string>]  


ALIASES
    None


REMARKS
    None
然后,当我导入模块时,两个函数都没有任何公共参数:

PS> Import-Module .\testfunc.psm1
PS> (Get-Command test-differentnamedparams).Parameters.Count
2
PS> (Get-Command test-differentnamedparams).Parameters | Format-Table -AutoSize

Key   Value
---   -----
hello System.Management.Automation.ParameterMetadata
bye   System.Management.Automation.ParameterMetadata

PS> (Get-Command test-noparams).Parameters.Count
0
我尝试了一些方法,看看它们是否能带来不同:

  • 使用导出模块成员显式导出函数
  • 使用将脚本模块作为嵌套模块导入的清单
  • 使用脚本并通过
    将其包括在内\testfunc.ps1
    而不是模块
  • 直接在shell中定义函数
他们都没有改变什么

什么决定函数是否具有公共参数?什么会导致他们不支持?

仅支持。

使脚本/函数成为高级函数的显式方法是使用
[CmdletBinding()]
属性修饰其
参数(…)

然而,正如他自己所发现的,使用每参数
[parameter()]
属性隐式地使脚本或函数成为高级脚本或函数

  • 但是,请注意,除
    [parameter()]
    -如
    [AllowNull()]
    [Alias()]
    之外的每参数属性本身并不构成脚本/函数和高级函数

发现给定脚本/函数是否高级(支持公共参数)的一种简便方法是将其名称传递给
获取帮助

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

function test-noparams() {
    Write-Host 'None'
}

function test-differentnamedparams([string]$hello, [switch]$bye) {
    Write-Host "names that don't conflict with common params"
}
# Define a NON-advanced function - no [CmdletBinding()] or [Parameter()] attributes.
PS> function foo { param([string] $bar) 'hi' }; Get-Help foo

NAME
    foo

SYNTAX
    foo [[-bar] <string>]  


ALIASES
    None


REMARKS
    None

很高兴知道这一点,谢谢-在函数定义时发出警告确实会更有帮助。我已将信息添加到答案中。如果你决定报告一个问题,请在我的答案中添加一个链接。我在这里整理了我的其他评论。
# Define an ADVANCED function IMPLICITLY - note the [Parameter(Mandatory)] attribute 
# FOR PARAMETER $bar.
PS> function foo { param([Parameter(Mandatory)] [string] $bar) 'hi' }; Get-Help foo

NAME
    foo

SYNTAX
    foo [[-bar] <string>]  [<CommonParameters>]


ALIASES
    None


REMARKS
    None
# Define advanced function that mistakenly names a a parameter for
# a common parameter:
PS> function foo { [CmdletBinding()] param([string] $Verbose) 'hi' }
# NO error is reported at this point.

# Later invocation of the function, including introspection of its parameters
# when you pass it to Get-Help, then surfaces the problem:
PS> Get-Help foo
Get-Help : A parameter with the name 'Verbose' was defined multiple times for the command.
At line:1 char:1
+ Get-Help foo
+ ~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [Get-Help], MetadataException
    + FullyQualifiedErrorId : ParameterNameAlreadyExistsForCommand,Microsoft.PowerShell.Commands.GetHelpCommand