Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell [System.Collections.Generic.List[string]]作为返回值_Powershell_Return Type_Generic List - Fatal编程技术网

Powershell [System.Collections.Generic.List[string]]作为返回值

Powershell [System.Collections.Generic.List[string]]作为返回值,powershell,return-type,generic-list,Powershell,Return Type,Generic List,我需要/希望从函数返回[System.Collections.Generic.List[string]],但它正被包含在System.Object[]中 我有这个 function TestReturn { $returnList = New-Object System.Collections.Generic.List[string] $returnList.Add('Testing, one, two') return ,@($returnList) } $test

我需要/希望从函数返回[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
它以System.Object[]的形式返回,如果我将返回行更改为

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

当列表中有一个项时,它返回一个[System.String],如果有多个项,则在这两种情况下都返回一个System.Object[]。列表中是否存在不能用作返回值的奇怪内容

现在,奇怪的是,我认为如果我像这样键入接收值的变量,它会起作用

[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[],返回的元素类型为[System.Collections.Generic.List[string]]。但同样由于它的隐式展开,PowerShell在按需键入时使用了某种技巧

稍后,语法[Type]$Var Type约束变量。它基本上锁定了该变量的类型。因此,对.GetType的后续调用将返回该类型

这些问题是由于PowerShell如何在输出时隐式展开数组造成的。典型的解决方案(在某种程度上取决于类型)是在返回之前加上一个,或者确保调用端的数组,方法是键入约束变量(如问题中所示),或者包装或强制转换返回本身。后者可能看起来像:

$testList = [System.Collections.Generic.List[string]]TestReturn
$testList.GetType().FullName
若要确保在标量返回是可能的情况下使用数组,并且假设在return语句之前没有使用,则可以在调用端使用数组子表达式:

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

如果删除数组子表达式,我相信会处理类似的问题。。。在前面加一个逗号。下面的代码似乎有效:

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

    return , $returnList
}

$testList = TestReturn
$testList.GetType().FullName
注意:从技术上讲,这会导致返回[Object[],返回的元素类型为[System.Collections.Generic.List[string]]。但同样由于它的隐式展开,PowerShell在按需键入时使用了某种技巧

稍后,语法[Type]$Var Type约束变量。它基本上锁定了该变量的类型。因此,对.GetType的后续调用将返回该类型

这些问题是由于PowerShell如何在输出时隐式展开数组造成的。典型的解决方案(在某种程度上取决于类型)是在返回之前加上一个,或者确保调用端的数组,方法是键入约束变量(如问题中所示),或者包装或强制转换返回本身。后者可能看起来像:

$testList = [System.Collections.Generic.List[string]]TestReturn
$testList.GetType().FullName
若要确保在标量返回是可能的情况下使用数组,并且假设在return语句之前没有使用,则可以在调用端使用数组子表达式:

$testList = @( TestReturn )
$testList.GetType().FullName
我相信会处理类似的问题

此外,您还可以选择使用[CmdletBinding]属性,然后调用。默认情况下,它将保留该类型

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
对于数组,应指定类型

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
我只是想添加一些关于我通常在函数中使用什么以及如何控制行为的信息。

此外,您还可以选择使用[CmdletBinding]属性,然后调用。默认情况下,它将保留该类型

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
对于数组,应指定类型

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

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

我猜默认情况下,PowerShell将采用System.Array,但如果执行[collections.generic.list[string]]$testList=TestReturn,即使函数返回字符串,它也应该可以正常工作。我猜默认情况下,PowerShell将采用System.Array,但如果执行[collections.generic.list[string]]$testList=TestReturn,即使函数返回字符串,它也应该可以正常工作。似乎我忘记了如何正确处理展开行为,然后将其归因于该类型。我一直在绞尽脑汁,想我可能也有办法解决这个问题。我将所有代码移动到类中以完全避免管道,并且我刚刚验证了展开行为仅在函数中存在。正如预期的那样,类不会做意外的事情。我正在致力于对当前基于函数的代码进行短期修复,但伙计,我期待着转向类。这就是管道污染。斯佩尔切克和我,我们相处不好。时间不早了,我很高兴能提醒你。顺便说一句,我用的是同一个词。似乎我忘了如何正确地处理展开
avior,然后将其归因于该类型。我一直在绞尽脑汁,想我可能也有办法解决这个问题。我将所有代码移动到类中以完全避免管道,并且我刚刚验证了展开行为仅在函数中存在。正如预期的那样,类不会做意外的事情。我正在致力于对当前基于函数的代码进行短期修复,但伙计,我期待着转向类。这就是管道污染。斯佩尔切克和我,我们相处不好。时间不早了,我很高兴能提醒你。顺便说一句,我用的是同一个词。老兄,我希望几年前我就知道这个把戏。这些年来,我浪费了太多的时间追踪管道污染。很多时候我都希望有一个指令来禁用管道作为函数返回机制,但事实就是这样。我现在有这么多的代码,最好只是因为其他原因重构为类,并获得可预测的行为作为奖励。但是学习新东西总是好的我只是通过编写C cmdlet才知道这一点。它真的很有用。我会小心使用PowerShell类。它们在基本方面做得很好,但在GitHub上仍然有很多悬而未决的问题,我相信它们的引入主要是为了支持DSC。同样,我仍然用C编写任何类。我的需求非常简单,我的知识也更简单。到目前为止,这些课程都很有效,但对我来说,学习不同的思维方式是一个巨大的学习曲线。希望我不会遇到任何交易破坏者。我可能需要在GitHub周围闲逛一下,看看我是否能在关口解决任何潜在的问题。伙计,我希望我几年前就知道这个把戏。这些年来,我浪费了太多的时间追踪管道污染。很多时候我都希望有一个指令来禁用管道作为函数返回机制,但事实就是这样。我现在有这么多的代码,最好只是因为其他原因重构为类,并获得可预测的行为作为奖励。但是学习新东西总是好的我只是通过编写C cmdlet才知道这一点。它真的很有用。我会小心使用PowerShell类。它们在基本方面做得很好,但在GitHub上仍然有很多悬而未决的问题,我相信它们的引入主要是为了支持DSC。同样,我仍然用C编写任何类。我的需求非常简单,我的知识也更简单。到目前为止,这些课程都很有效,但对我来说,学习不同的思维方式是一个巨大的学习曲线。希望我不会遇到任何交易破坏者。我可能需要在GitHub周围转一转,看看我是否能在关卡上解决任何潜在的问题。