Powershell 我不知道';无法理解带有begin/process/end块的函数上的参数绑定
我这样称呼它,假设我已经在字典中添加了值(为了简洁起见,这里删除了) 这是我的难题 上述方法非常有效。但是,下面没有说明key/value参数中的差异Powershell 我不知道';无法理解带有begin/process/end块的函数上的参数绑定,powershell,Powershell,我这样称呼它,假设我已经在字典中添加了值(为了简洁起见,这里删除了) 这是我的难题 上述方法非常有效。但是,下面没有说明key/value参数中的差异 $dict = New-Object 'System.Collections.Generic.Dictionary[string,string]' $dict.GetEnumerator() | Format-File -Path $updatePath 上面抛出了一个异常。第一次调用函数时,它似乎获得默认值,但在处理时,键/值参数设置正确 为
$dict = New-Object 'System.Collections.Generic.Dictionary[string,string]'
$dict.GetEnumerator() | Format-File -Path $updatePath
上面抛出了一个异常。第一次调用函数时,它似乎获得默认值,但在处理时,键/值参数设置正确
为什么不在函数调用时设置键/值,这有点道理,但这也意味着我的心智模型已关闭
所以我的问题是双重的
Begin
块中,管道绑定参数将为$null
,如果有,则使用其默认值。考虑到价值的管道化还没有开始,这是有道理的
在过程
块中,参数将是管道中的当前项
在结束
块中,参数将是过程
块中的最后一个值,除非验证参数时出现异常,在这种情况下,它将使用默认值(或$null
)
如何验证从管道中输入的值?
无法签入开始
块
最好的方法是使用[Validate
属性,就像使用[ValidateNotNullOrEmpty()]
一样
使用throw
作为默认值的示例在某些情况下很有用,但它们是一种巧妙的解决方法。问题是,您不需要它们,因为您已经将参数声明为必需参数
例如,您可以使用[ValidateScript({$value-eq'MyString'})]
而不是使用默认值
由于来自[ValidateScript()]
的错误消息很糟糕,您可以结合使用以下技术:
函数格式文件{
param(
[参数(必需=$true,位置=1,ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullOrEmpty()]
[ValidateScript({
($我的.Length-le 10)-或$(抛出“我的自定义异常消息”)
} )]
[字符串]$key
)
}
无论是否为管道参数,使用
[ValidateScript()]
都会起作用。管道值在过程中进行处理
这就是关键所在。在此之前,您不会看到它们,因为函数启动时它们可能不存在(管道流).Validation为每个管道输入运行?这很好。亲爱的上帝,ValidateScript
的错误输出很糟糕。是的,它在每个管道输入上运行。如果您使用-ErrorAction Stop
(或其等效首选项)调用它当抛出异常时,它将停止,但如果没有,它将继续使用管道。ValidateScript属性是否比普通函数中的默认值技巧有任何优势,或者在处理管道输入时,它的优势更多的是在更合适的时间绑定?我想继续使用默认值技巧I在一般情况下,因为它比较短,只有在有明确的理由时才使用validatescript。我想不出具体的优势,但在发布这个问题之前,我也没有想到它在管道方面的用途。但在我看来,这是“正确方式”的继承优势。我还认为它保持了(经常是混乱的)验证代码从函数体中删除,使其更干净。我喜欢这种分离;我认为参数验证应该尽可能在声明中进行。感谢知识渊博的响应,我的powershell知识今天有了很大的提高:)
$dict = New-Object 'System.Collections.Generic.Dictionary[string,string]'
$dict.GetEnumerator() | Format-File -Path $updatePath
function Format-File {
param(
[Parameter(Mandatory = $true, Position = 0)]
[ValidateNotNullOrEmpty()]
[string] $path=$(throw "path is mandatory ($($MyInvocation.MyCommand))"),
[Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[string] $key=$(throw "key is mandatory ($($MyInvocation.MyCommand))"),
[Parameter(Mandatory = $true, Position = 2, ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[string] $value=$(throw "value is mandatory ($($MyInvocation.MyCommand))")
)
}