使用PowerShell,历史上不需要yield return
;因为那基本上就是管道。
但是,对于PS5的类,方法无法写入管道。因此,是否有任何选项可以模仿Powershell类方法中的yield return
/ pipeline
行为?
此代码将数据返回到管道;我们可以看到变量$ global:i由函数更新,然后在函数的下一次迭代之前由管道中的下一步读取的值:
[int]$i = 0
function Get-PowerShellProcesses() {
Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{$global:i++; $_}
}
Get-PowerShellProcesses | %{"$i - $($_.ProcessName)}
输出:
1 - powershell
2 - powershell_ise
如果我们对类的方法做同样的事情,除了在传递给管道之前收集完整的结果集之外,一切都是一样的。
[int]$i = 0
class Demo {
Demo(){}
[PSObject[]]GetPowershellProcesses() {
return Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{$Global:i++; $_}
}
}
$demo = New-Object Demo
$demo.GetPowerShellProcesses() | %{"$i - $($_.ProcessName)"}
输出:
2 - powershell
2 - powershell_ise
我猜测那里没有解决方案;但希望有一些东西。
在上面的例子中显然它没有。但是,如果我们不需要完整的结果集,这确实会产生影响;例如假设在函数调用之后我们有一个| Select-Object -First 10
,但是返回成千上万的结果有一个昂贵的操作,我们会看到显着的性能损失。
Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{return $_}
错误:Not all code path returns value within method.
Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{return $_}
return
错误:Invalid return statement within non-void method
[void]
/ $null
返回:Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{return $_}
return [void] #or return $null
没有错误;但就好像只调用了最后一个return语句;所以我们没有数据。
Get-Process | ?{$_.ProcessName -like '*powershell*'} | %{yield return $_}
错误:The term 'yield' is not recognized ...
简单的解决方法是使用带有yield return
的C#类或传统的PowerShell函数。