我有以下代码(简化,这不是我的实际用例):
$actions = @()
@(1,2,3) | ForEach-Object {
$localCopy = $_
$actions += {Write-Output $localCopy}
}
$actions | ForEach-Object { $_.Invoke() }
输出:
3
3
3
但是,我想要的输出是:
1
2
3
在C#之类的东西中,分配 $ localCopy 变量就足以创建一个新的局部变量,委托在调用时会引用该变量。但是,Powershell有不同的范围 - 我使用Powershell 3.0,因此委托在自己的范围内被调用(参见this question)。我尝试使用 $ localCopy 上的 $ local:前缀,但这不起作用(根据范围规则的预期)。
因此,如果在自己的范围内调用委托,这是不可能完成的?如何分配执行委托时可用的临时变量?我理解使用 NewScriptBlock 可能有一个解决方案,但这似乎过于复杂,我认为这将是一个简单的操作。
答案 0 :(得分:4)
您需要使用GetNewClosure(http://msdn.microsoft.com/en-us/library/system.management.automation.scriptblock.getnewclosure(v=vs.85).aspx)。这是一个例子:
$actions = @()
@(1,2,3) | ForEach-Object {
$localCopy = $_
$actions += {Write-Output $localCopy}.GetNewClosure()
}
$actions | % { $_.Invoke() }
答案 1 :(得分:1)
您可以执行以下操作立即评估局部变量:
$actions = @()
@(1,2,3) | ForEach-Object {
$localCopy = $_
$actions += [ScriptBlock]::Create("Write-Output $localCopy")
}
$actions | ForEach-Object { $_.Invoke() }