我正在玩代理功能,我想完全理解我正在查看的所有代码。
鉴于此:
$MetaData = New-Object System.Management.Automation.CommandMetaData
(Get-Command Get-ChildItem)
[System.Management.Automation.ProxyCommand]::Create($MetaData)
以下是我不明白的输出代码片段:
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
$PSBoundParameters['OutBuffer'] = 1
}
我只是好奇PSBoundParameters在这里发生了什么。它只是测试它是否可以获得outbuffer的句柄?为什么呢?
编辑:我不能解决的其他问题是它调用TryGetValue的方式,因为查看定义:
($PSBoundParameters | gm -Name trygetvalue).definition
bool TryGetValue(string key, [ref] System.Object value),
bool IDictionary[string,Object].TryGetValue(string key, [ref] System.Object value),
bool IReadOnlyDictionary[string,Object].TryGetValue(string key, [ref] System.Object value)
看起来它需要第三个参数:(string key, [ref]System.Object valueToBeStored)
它只是传递一个字符串和一个[ref] $对象,但是#34;值"没有字符串。 "值"我相信你用它来检索从字典查找中找到的值。
答案 0 :(得分:1)
OutBuffer
@MathiasR.Jessen可以在Get-Help about_CommonParameters
的评论文档中按^获取{p}}。
-OutBuffer
别名:ob
确定之前在缓冲区中累积的对象数 任何对象都通过管道发送。如果省略此参数, 对象在生成时发送。
此资源管理参数专为高级用户设计。 使用此参数时,Windows PowerShell不会调用 管道中的下一个cmdlet,直到生成的对象数 等于OutBuffer + 1.此后,它按原样发送所有对象 生成。
关于$PSBoundParameters['OutBuffer']
与参数OutBuffer
之间的差异;空无一人。 $PSBoundParameters
是一个字典,其中包含通过值传递到当前函数/ cmdlet的所有参数。您可以通过运行Get-Help about_Automatic_Variables
^:
$ PSBoundParameters
包含传递给脚本的参数字典 或功能及其当前值。此变量仅具有值 在声明参数的范围内,例如脚本或函数。 您可以使用它来显示或更改参数的当前值 或者将参数值传递给另一个脚本或函数。
例如:
function Test { param($a, $b) # Display the parameters in dictionary format. $PSBoundParameters # Call the Test1 function with $a and $b. test1 @PSBoundParameters }
您显示的代码看起来像proxy function。因此,您可能会在代码中进一步查看以下行:
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
这里将$PSBoundParameters
哈希表/字典传递给变量$wrappedCmd
中定义的命令,所有命名值都作为该函数的参数值传递(即每个字典条目映射其值)到具有相同名称的命令参数)。这称为Splatting(通过运行Get-Help about_splatting
更多信息):
Splatting是一种将参数值集合传递给a的方法 命令为单位。 Windows PowerShell关联了每个值 使用命令参数进行集合。 Splatted参数值是 存储在命名的splatting变量中,看起来像标准的 变量,但以At符号(@)而不是美元符号开头 ($)。 At符号告诉Windows PowerShell您正在传递 值的集合,而不是单个值。
Splatting使您的命令更短,更容易阅读。您可以 在不同的命令调用中重用splatting值并使用 splatting从$ PSBoundParameters传递参数值 自动变量到其他脚本和函数。
从Windows PowerShell 3.0开始,您还可以使用splatting 代表命令的所有参数。
这里有一篇很好的文章:https://mcpmag.com/articles/2013/07/16/common-parameter-part-4.aspx。我也在下面尝试了自己的解释:
通常,它用于提高性能。通常,PowerShell通过获取单个行/对象并在获取下一个对象/行之前将其一直传递到管道,就像foreach / iterator循环一样。 e.g。
Import-CSV 'abc.csv' | Export-CSV '123.csv'
有点像这样(伪代码):
$reader = New-Object 'PseudoCode.CSVReader' -ArgumentList 'abc.csv'
$writer = New-Object 'PseudoCode.CSVReader' -ArgumentList '123.csv'
while ($data = $reader.ReadLine())
{
$writer.WriteLine($data)
}
在某些情况下这很好;它意味着你不会在内存中(通常)保留太多内容,因为你一点一点地抓住并使用数据。但是,有时候你可以通过处理更大的块来获得更好的性能。我经常使用的类比是用手填充沙坑。鉴于这个过程:
考虑一次移动1个谷物,一次移动1个桶,每次移动1个沙坑。
现在的问题是:什么是最佳的铲斗尺寸。
这里我们的水桶是我们的外出手。
你说:
看起来它需要第三个参数:(字符串键,[ref] System.Object valueToBeStored)
没有第三个参数;参数是:
string key
[ref]System.Object valueToBeStored
Key
定义要获取的值的名称。
valueToBeStored
是我们提取的价值。它作为引用传递,因为如果存在这样的值,则该值将填充给定键的值(在这种情况下,函数TryGetValue返回true
以及分配值)。如果字典中不存在这样的键,则函数返回false
,并且传递给参数valueToBeStored
的变量保持其原始值(在这种情况下为$null
)。有关详情,请参阅documentation on TryGetValue。
如果[ref]
使您感到困惑,则会导致该参数用作参考变量。您可以通过get-help about_ref
^
TOPIC
about_Ref
简短说明
描述如何创建和使用引用变量类型。
详细说明
您可以使用引用变量类型来允许方法更改 传递给它的变量的值。
当[ref]类型与对象关联时,它返回一个引用 到那个对象。如果引用与方法一起使用,则该方法可以 引用传递给它的对象。如果在其中更改了对象 该方法,更改显示为变量值的更改 当控制返回到调用方法时。
要使用引用,参数必须是引用变量。如果是 不,抛出InvalidArgument异常。
方法调用中使用的参数必须与所需类型匹配 按方法。