[System.Collections.Generic.List[string]] 作为 return 值

[System.Collections.Generic.List[string]] as return value

我有一个 need/want 到 return 一个 [System.Collections.Generic.List[string]] 函数,但它被覆盖到 System.Object[]

我有这个

function TestReturn {
    $returnList = New-Object System.Collections.Generic.List[string]
    $returnList.Add('Testing, one, two')

    return ,@($returnList)
}

$testList = TestReturn
$testList.GetType().FullName

其中 return 将其作为 System.Object[],如果我将 return 行更改为

return [System.Collections.Generic.List[string]]$returnList

return [System.Collections.Generic.List[string]]@($returnList)

如果列表中只有一项,则 return 为 [System.String],如果有多个项目,则为 System.Object[],在这两种情况下。列表有什么奇怪的地方不能用作 return 值吗?

现在,奇怪的是(我认为)如果我输入接收值的变量,它确实有效,就像这样。

[System.Collections.Generic.List[string]]$testList = TestReturn

但这似乎是某种奇怪的强制转换,其他数据类型不会发生这种情况。

如果删除数组子表达式 @(...) 并且只在前面加一个逗号。以下代码似乎有效:

function TestReturn {
    $returnList = New-Object System.Collections.Generic.List[string]
    $returnList.Add('Testing, one, two')

    return , $returnList
}

$testList = TestReturn
$testList.GetType().FullName

注意:从技术上讲,这会导致 [Object[]] 的 return 具有类型为 [System.Collections.Generic.List[string]] 的单个元素。但同样由于隐式展开,它会欺骗 PowerShell 按需要输入。

关于你后面的观点,语法 [Type]$Var 类型限制了变量。它基本上锁定了该变量的类型。因此,随后对 .GetType() 的调用将 return 该类型。

这些问题是由于 PowerShell 如何在输出时隐式展开数组。典型的解决方案,在某种程度上取决于类型,是在 return 之前加上 , 或确保调用方的数组,通过类型约束变量如问题中所示,或包装或铸造 return 本身。后者可能类似于:

$testList = [System.Collections.Generic.List[string]]TestReturn
$testList.GetType().FullName

为了在标量 return 可能时确保数组并假设您没有在 return 语句之前使用 , ,您可以在调用端使用数组子表达式:

$testList = @( TestReturn )
$testList.GetType().FullName

我相信 处理类似的问题

除了, you also have the option to use the [CmdletBinding()] attribute and then just call $PSCmdlet.WriteObject。默认情况下,它将保留类型。

function Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $PSCmdlet.WriteObject($List)
    }
}
$List = Test-ListOutput
$List.GetType()
$List.GetType().FullName

对于数组,您应该指定类型。

function Test-ArrayOutput {
    [CmdletBinding()]
    Param ()
    Process {
        [Int32[]]$IntArray = 1..5
        $PSCmdlet.WriteObject($IntArray)
    }
}
$Arr = Test-ArrayOutput
$Arr.GetType()
$Arr.GetType().FullName

默认情况下 PSCmdlet.WriteObject() 的行为是不枚举集合 ($false)。如果将值设置为 $true,您可以在管道中看到行为。

function Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $List.Add("This is another string")
        $List.Add("This is the final string")
        $PSCmdlet.WriteObject($List, $true)
    }
}

Test-ListOutput | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object

(Test-ListOutput).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


# No boolean set defaults to $false
function Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $List.Add("This is another string")
        $List.Add("This is the final string")
        $PSCmdlet.WriteObject($List)
    }
}

Test-ListOutput | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     List`1                                   System.Object

(Test-ListOutput).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     List`1                                   System.Object

只是想添加一些关于我通常在函数中使用的内容以及如何控制行为的信息。