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

Find ArrayList members and (Get-Process).id vs (1,2,3).ToString()

让我们看下面的代码:

$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() 是数组和数字元素的方法。数组上的 ToString() 方法是 return 对象类型“System.Object[]”。一个更好的例子是:

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

这表明对列表的操作,当不是列表操作时,对元素进行操作(展开),然后重新回滚到列表。看来Powershell是务实的,但至少是一致的。

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

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

$array | Get-Member

您会看到它为您提供了 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)

您会注意到,每次将项目添加到数组列表时,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()

而且您可以 add/remove 与处理数组列表的方式相同。