添加输出流时,布尔函数会更改返回的数据类型

Kas*_*urg 2 powershell

我在理解 powershell 的内部工作原理时遇到了一些麻烦。以这个例子为例。我有一个布尔函数 (Test-MyCode),只要省略了 Write-Output cmdlet,它就可以正常工作。添加 Write-Output cmdlet 后,返回类型将更改为 Object[] 数组。

.GetType() 可用于查看数据类型。

为什么是这样?

function Test-MyCode
{
    if( 2 -gt 0)
    {
        Write-Output "This function will return false"
        return $false
    }
    else
    {
        Write-Output "could return true if condition is changed"
        return $true
    }
}

function Invoke-MyCode
{
    Write-Output "this is main"
    Write-Output "do stuff"
    # Test-MyCode is configured to return false... yet its true
    if (Test-MyCode)
    {
        Write-Output "yep, no longer boolean"
    }

}

Invoke-MyCode
Run Code Online (Sandbox Code Playgroud)

Mat*_*sen 5

来自Get-Help Write-Output

NAME
    Write-Output

SYNOPSIS
    Sends the specified objects to the next command in the pipeline. If the
    command is the last command in the pipeline, the objects are displayed in
    the console.
Run Code Online (Sandbox Code Playgroud)

我认为您的主要困惑源于这样一个事实,即PowerShell 函数不是静态绑定到返回某种类型的

return关键字不工作完全一样C#,但大致意思是:

  1. 调用关键字Write-Ouput后的表达式结果return
  2. 退出当前作用域

有关详细信息about_Return,请参阅,about_Functionsabout_Functions_OutputTypeAttribute帮助文件


在上面的简单示例中,我会被创建一个包含字符串和结果的新自定义对象所吸引,但此“解决方案”的适用性可能会有所不同:

function Test-MyCode
{
    if( 2 -gt 0)
    {
        New-Object psobject -Property @{
            Message = "This function will return false"
            Result  = $false
        }
    }
    else
    {
        New-Object psobject -Property @{
            Message = "could return true if condition is changed"
            Result  = $true
        }
    }
}

function Invoke-MyCode
{
    Write-Host "this is main"
    Write-Host "do stuff"
    # Test-MyCode is configured to return false... yet its true
    if (($codetest = Test-MyCode).Result)
    {
        Write-Host $codetest.Message
    }
}

Invoke-MyCode
Run Code Online (Sandbox Code Playgroud)

请注意,Write-Output当我使用以下命令将对象“转储”到管道上时是如何隐含的New-Object