查找ArrayList成员和(Get-Process).id与(1,2,3).ToString()

时间:2020-09-16 04:31:32

标签: arrays powershell oop arraylist powershell-7.0

让我们看看下面的代码:

$r = New-Object System.Random
$r.GetType()
$r | Get-Member

我想我了解它是如何工作的。但是,当我用ArrayList替换Random对象时:

$a = New-Object System.Collections.ArrayList
$a.GetType()
$a | Get-Member

[问题1] Get-Member调用产生错误:“您必须为Get-Member cmdlet指定一个对象”。什么? $ a不是对象吗? “ $ a.gettype()”表示正确。

[问题2]我了解ArrayList可以容纳其他对象,但是如何获取ArrayList本身的成员,例如从文档中找到的add(),clear()等? ISE也了解成员。

让我们看一下以下两个类似的结构:

$p = Get-Process
$p.GetType()
$p | Get-Member
$p.id[2]

$L = @(3,1,4,1,5,9,2,6,5,3)
$L.GetType()
$L | Get-Member
$L.ToString()[2]

[问题3] $ p是[处理对象]的数组,但是,Get-Member不会显示数组本身的成员,而是显示该数组持有的对象的成员,这有意义吗?

[问题4]数组$ p没有成员“ id”,但是$ p.id对数组的每个元素进行操作,生成@($ p [0] .id,$ p [ 1] .id,...)。让我们接受这是它在Powweshell中的工作原理,然后对数组$ L也应如此,但是$ L.ToString()会产生文字字符串“ System.Object []”,即15个字符! $ L.ToString()[2]是“ s”!为什么没有一致性?

[编辑]问题4使用了一个错误的示例,因为ToString()是数组以及number元素的方法。数组上的ToString()方法将返回对象类型“ System.Object []”。一个更好的例子是:

@([byte]67, [byte]97, [byte]116).tochar($null)
C
a
t

表示对列表的操作(不是列表操作)对元素(展开)进行操作,然后重新回滚到列表。 Powershell似乎很实用,但至少是一致的。

1 个答案:

答案 0 :(得分:1)

正如Lee_Dailey先生所说,$listofsomethings | get-member将应用于变量中的实际对象。如果它们都是相同的,那么powershell可以解决这个问题,并且只会输出一次信息。但是,请看这个例子。

$array = [int]2,[string]"doug",[float]19.83

$array | Get-Member

您将看到它为您提供了3种不同类型的详细信息,因为此数组中有3种不同的类型。另一方面,如果您这样做

Get-Member -InputObject $array

您将看到有关数组容器本身的信息。此外,以下命令也将查看容器。

   $array.GetType().BaseType

要查看容器集合中每个成员的类型(不使用$array | gm的Powershell自动展开),您必须遍历它们。

$array.ForEach{$_.gettype()}
$array.ForEach{$_.gettype().basetype}

现在知道了这一点,应该清楚为什么$p.id起作用了。Powershell通过有效地在后台运行来“帮助”您

$p | foreach id

或以与$ array foreach相同的方式编写

$p.foreach{$_.id}

$ arraylists类似于数组,因为它们可以包含不同类型的对象。

$arraylist = New-Object System.Collections.ArrayList
$arraylist.Add([int]2)
$arraylist.Add([string]"Stack Overflow")
$arraylist.Add([double]32.80)

您会注意到,每次将项目添加到arraylist时,powershell都会输出该项目添加位置的索引。删除此$null = $arraylist.add(...)是很平常的事。仅此烦恼就足以阻止它的使用,但是不赞成使用System.Collections.Generic.List列表的事实应该已经使您远离了它。您可以指定列表用于的项目类型,例如[string],[int],[object]等。添加项目时,它也不会产生分散索引号的副作用。

您可以创建这样的列表

$list = new-object System.Collections.Generic.List[string]

$list = [System.Collections.Generic.List[string]]::new()

您可以使用与数组列表相同的方式添加/删除。