PowerShell类方法的收益率返回等价物

时间:2017-11-08 19:02:59

标签: class powershell yield-return

使用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函数。

0 个答案:

没有答案