代码之家  ›  专栏  ›  技术社区  ›  Ralf_Reddings

在不使用管道的情况下,数组参数的值将被视为多行字符串

  •  3
  • Ralf_Reddings  · 技术社区  · 2 年前
    Function foo{
        [CmdletBinding()]
        Param(
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [array]$path
        #[string[]]$path    #I tried this too, same issue as above.
        )
    
        Begin{"---begin---" ; $path}
        Process{"---Process---" ; $path}
        End{"---End---" ; $path}
        }
    

    在没有管道的情况下,将多个值传递给 path 参数总是被视为多行字符串, foo -path 'C:\temp\green', 'C:\temp\blue', 'C:\temp\red' :

    ---begin---
    red
    blue
    green
    ---Process---
    red
    blue
    green
    ---End---
    red
    blue
    green
    

    对于管道,值为 路径 被正确地视为阵列元素, foo -path 'red', 'blue', 'green' :

    ---begin---
    ---Process---
    red
    ---Process---
    blue
    ---Process---
    green
    ---End---
    green
    

    我不理解这种行为的突然变化,我预计这两种情况都会调用 foo (带或不带管道)将值输出到 路径 作为单个阵列元件。

    win11/pwsh 7.4

    1 回复  |  直到 2 年前
        1
  •  3
  •   mklement0    2 年前

    这个 process 根据管道中的每个值调用块,逐个传递并处理每个项。当您将数组绑定到参数时,情况并非如此。如果您想平等地处理这两种情况,即从管道绑定和参数绑定,则需要在参数上进行循环。另请参阅 process from about Functions Advanced Methods .

    Function foo {
        [CmdletBinding()]
        Param(
            [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
            [array] $path
        )
    
        Begin {
            '---begin---' ; $path
        }
        Process {
            foreach ($item in $path) {
                '---Process---' ; $item
            }
        }
        End {
            '---End---' ; $path
        }
    }
    

    顺便说一句,在不使用管道时,值不会被视为多行字符串,它们总是被视为参数的类型,在这种情况下是数组。你总是需要一个循环,无论它是否来自管道。

    function foo {
        [CmdletBinding()]
        Param(
            [Parameter(ValueFromPipeline)]
            [array] $path
        )
    
        Process {
            $path.GetType()
        }
    }
    
    foo 1, 2, 3
    1, 2, 3 | foo
    
    推荐文章