gpt4 book ai didi

PowerShell 5.1 为什么这两个函数返回不同的类型

转载 作者:行者123 更新时间:2023-12-05 01:04:12 24 4
gpt4 key购买 nike

function Main {
$result1 = DoWork1
$result1.GetType()

$result2 = DoWork2
$result2.GetType()
}

function DoWork1 {
$result1 = Invoke-Sqlcmd -Query "select top 1 * from customer" -ServerInstance "(localdb)\MSSQLLocalDB" -Database "Database1" -OutputAs DataTables
#assign to variable then return
return $result1
}

function DoWork2 {
#return results without assigning to variable
return Invoke-Sqlcmd -Query "select top 1 * from customer" -ServerInstance "(localdb)\MSSQLLocalDB" -Database "Database1" -OutputAs DataTables
}

Main

这是意外的输出:

IsPublic IsSerial Name                                     BaseType                                                                                    
-------- -------- ---- --------
True False DataRow System.Object
True True DataTable System.ComponentModel.MarshalByValueComponent


最佳答案

使用之前问答中的类似示例,重现相同的行为:

function Invoke-SqlExample {
$dtt = [System.Data.DataTable]::new()
[void] $dtt.Columns.Add('Name')
$row = $dtt.NewRow()
$row.Name = "Hello"
$dtt.Rows.Add($row)
, $dtt
}

function Main {
$result1 = DoWork1
$result1.GetType()

$result2 = DoWork2
$result2.GetType()
}

function DoWork1 {
$result1 = Invoke-SqlExample
[pscustomobject]@{
Function = $MyInvocation.MyCommand.Name
Type = $result1.GetType().Name
} | Out-Host
return $result1

# Immediate fixes:
# return , $result1
# Write-Output $result1 -NoEnumerate
# $PSCmdlet.WriteObject($result1, $false) !! Only if Advanced Function
}

function DoWork2 {
return Invoke-SqlExample
}

Main

你会得到的输出是:

Function Type
-------- ----
DoWork1 DataTable


IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False DataRow System.Object
True True DataTable System.ComponentModel.MarshalByValueComponent

我们可以看到 DataTable 的展开仅在之前分配给变量时才完成,即使变量 ($result1 in DoWork1 仍然是 DataTable 类型)。

这可以解释为,DoWork2 发生在单个管道中,而 DoWork1 发生在两个管道中,首先是 Invoke-SqlExample< 的输出 被收集在一个变量中,然后作为输出发出(这是触发展开的地方)。这是基于假设,可能并不完全正确。

作为 iRon suggested in his helpful comment从前面的答案中,立即修复让 DoWork1 返回未触及的 DataTable 实例 (unrolled),我们可以使用 comma operator ,它将 DataTable 实例包装在一个数组中,然后在枚举期间丢失(函数的输出),因为它是一个元素的数组。另一种选择是使用 Write-Output -NeEnumerate .作为最后一种选择,我们也可以使用 $PSCmdlet.WriteObject(..., $false) 仅当功能是高级功能时


添加一个演示相同行为的类似示例,此示例由 mclayton in his helpful comment 提供:

function test {
, [Collections.Generic.List[string]]@(
'hello'
'world'
)
}

(& { test }).GetType() # => List`1
(& { $a = test; $a }).GetType() # => Object[]

关于PowerShell 5.1 为什么这两个函数返回不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72585395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com