困惑的Powershell返回了数组类型

时间:2015-05-22 19:04:26

标签: powershell

以下显示返回的类型不同取决于返回的行数。为什么这样设计?很容易做出假设,它总是返回一个数组并编写代码$a.Length $a | % { ....} ,当它只返回一行时会引发错误,除非它和& #39;写成$a = @(invoke-....),很容易忘记。

$a=Invoke-Sqlcmd -ServerInstance server "select 1 a"
$b=Invoke-Sqlcmd -ServerInstance server "select 1 a union all select 2"
$a.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    DataRow                                  System.Object

以下语句返回一个对象数组(BTW,为什么不是DataRow数组?)

$b.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array

但是,gm为两个变量返回相同的类型。为什么它的设计方式非常混乱。

问题:

  1. 当只返回一个项目时,删除数组的重点是什么?
  2. 为什么gm获取数组的项类型?如何gm数组?
  3. 为什么getType()在返回数组类型时无法返回项的数据类型?
  4. PS SQLSERVER:\> $a|gm
    
    
       TypeName: System.Data.DataRow
    
    Name              MemberType            Definition
    ----              ----------            ----------
    AcceptChanges     Method                void AcceptChanges()
    ......
    ToString          Method                string ToString()
    Item              ParameterizedProperty System.Object Item(int columnIndex) {get;set;}, System.Object Item(string co...
    a                 Property              int a {get;set;}
    
    
    PS SQLSERVER:\> $b|gm
    
    
       TypeName: System.Data.DataRow
    
    Name              MemberType            Definition
    ----              ----------            ----------
    AcceptChanges     Method                void AcceptChanges()
    ......
    ToString          Method                string ToString()
    Item              ParameterizedProperty System.Object Item(int columnIndex) {get;set;}, System.Object Item(string co...
    a                 Property              int a {get;set;}
    

1 个答案:

答案 0 :(得分:2)

  1. 大多数时候,在PowerShell中,返回对象的函数/ cmdlet只返回对象。如果要返回多个对象,则该函数只保留返回对象,直到完成为止。 PowerShell处理所有返回的对象,并为您提供一个数组。
  2. $a | gm$a的别名。通过管道调用它Get-Member来调用它时,您将其作为管道调用。在这种情况下,Get-Member -InputObject $a中的每个对象单独传递给.GetType(),因此它返回单个对象的类型。如果它们都是相同的,那么它只会显示一次,但它实际上会检查所有这些。您可以通过调用%来阻止这种情况,如果它是一个数组,它应该显示数组类型。
  3. 与上面类似,ForEach-Object获取它所调用的任何对象的类型,因此如果它是一个数组,则返回该数组;它不看个别元素。
  4. 我还想指出foreach()"hello" | % { $_ })和foreach($msg in "hello") { $msg }在数组上不使用时工作正常:$a.Lengthif ($a -is [Array]) { $itemCount = $a.Length } else { $itemCount = 1 } 也是如此

    要解决$a.Length在返回值是单个对象时无效的问题,它取决于您的powershell版本。

    在版本2中,您将看到您所看到的行为:您必须首先将其包装在数组中,或者测试具有以下内容的数组:

    $a

    但是,在powershell 3+中,即使FileOutputStream fo只是某个对象而不是数组,也可以执行fo.close()。它将返回1.长度可能不会显示在自动完成或智能感知中,但它会起作用。