[英]Confused Powershell returned array type
The following shows that the returned type are different depends on how many rows returned. 以下显示返回的类型不同,取决于返回的行数。 Why it's designed this way?
为什么这样设计? It's very easy to make assumption it always returns an array and write the code
$a.Length
$a | % { ....}
这很容易使假设它总是返回一个数组,编写代码
$a.Length
$a | % { ....}
which will raise error when it returns only one row, unless the it's written as $a | % { ....}
$a = @(invoke-....)
, which is easy to forget. 仅返回一行时会引发错误,除非它写为$a | % { ....}
$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
And the following statement returns an array of object (BTW, why not an array of DataRow?) 下面的语句返回一个对象数组(顺便说一句,为什么不是DataRow数组?)
$b.GetType()
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
However, gm
returns the same type for both variables. 但是,
gm
为两个变量返回相同的类型。 Why it's designed this way which can be very confused. 为什么以这种方式设计,这可能会非常混乱。
Question: 题:
gm
get item type of an array? gm
获取数组的项目类型? How to gm
of an array? gm
的数组? getType()
cannot return the data type of the item when it returns an array type? getType()
返回数组类型时不能返回该项目的数据类型? ? ?
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;}
gm
is an alias for Get-Member
. gm
是Get-Member
的别名。 When you call it by piping to it $a | gm
$a | gm
$a | gm
, you are invoking it as a pipeline. $a | gm
,您将其作为管道调用。 In this case, each object in $a
is individually passed to Get-Member
, so it returns the type of the individual object(s). $a
每个对象都单独传递给Get-Member
,因此它返回单个对象的类型。 If they are all the same, then it will only display it once, but it's actually checking all of them. Get-Member -InputObject $a
which should show you the array type if it is an array. Get-Member -InputObject $a
来防止这种情况,如果它是一个数组,则应显示数组类型。 .GetType()
gets the type of whatever object it's invoked on, so if it's an array, then it returns that; .GetType()
获取调用它的对象的类型,因此,如果它是一个数组,则返回该对象。 it's not looking at the individual elements. I also want to point out that %
( ForEach-Object
) and foreach()
work fine when not used on an array: "hello" | % { $_ }
我也想指出的是,
%
( ForEach-Object
)和foreach()
在阵列上没有使用正常工作: "hello" | % { $_ }
"hello" | % { $_ }
, as does foreach($msg in "hello") { $msg }
. "hello" | % { $_ }
,就像foreach($msg in "hello") { $msg }
。
To address the issue of $a.Length
not working when the return value is a single object, it depends on your powershell version. 要解决
$a.Length
在返回值是单个对象时不起作用的问题,这取决于您的Powershell版本。
In version 2, you will see the behavior you are seeing: you'll have to wrap it in an array first, or test for an array with something like: 在版本2中,您将看到所看到的行为:您必须首先将其包装在一个数组中,或者使用类似以下内容的数组进行测试:
if ($a -is [Array]) {
$itemCount = $a.Length
} else {
$itemCount = 1
}
But, in powershell 3+, you can do $a.Length
even if $a
is just some object and not an array. 但是,在Powershell 3+中,即使
$a
只是某个对象而不是数组,也可以执行$a.Length
。 It will return 1. Length may not show up in autocomplete or in intellisense, but it will work. 它将返回1。长度可能不会显示在自动完成或智能提示中,但可以使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.