在PowerShell中使用.NET集合(ArrayList、List等)的技巧

在PowerShell中使用.NET集合(ArrayList、List等)的技巧,powershell,Powershell,我刚刚意识到这一点,我通过艰苦的方式学到了这一点,所以我想与大家分享。考虑下面的字符串列表: >$list = New-Object -TypeName System.Collections.Generic.List[string] >$list.Add("x") >$list.Add("yy") >$list.Add("zzz") >$list x yy zzz 现在,如果您想获取列表中的项数,可以访问.Count属性,它会按预期为您提供“3” >$lis

我刚刚意识到这一点,我通过艰苦的方式学到了这一点,所以我想与大家分享。考虑下面的字符串列表:

>$list = New-Object -TypeName System.Collections.Generic.List[string]
>$list.Add("x")
>$list.Add("yy")
>$list.Add("zzz")
>$list
x
yy
zzz
现在,如果您想获取列表中的项数,可以访问.Count属性,它会按预期为您提供“3”

>$list.Count
3
但是,有时访问.Length而不是.Count会出错。在其他语言(如Python或C#)中,您会收到一个错误,说明此属性不可用。但在PowerShell中,如果在该对象上找不到它,它将遍历包含的对象并访问它们的属性。所以你最终得到了一个长度列表!惊喜

>$list.Length
1
2
3
您甚至可以调用方法

>$list.ToUpper()
X
YY
ZZZ
请注意,正如我所尝试的,此“功能”也适用于System.Collections.ArrayList。但它不适用于PowerShell的内置数组类型


这个“特征”叫什么?为什么设计成这样?这非常令人惊讶,而且容易出错。

Keith Hill在评论中提到,这是V3中名为成员枚举的新功能


请参阅devblogs.microsoft.com上的“”。

它被称为许多东西。成员枚举是最新的IIRC。看,我不喜欢这个新的“特性”(在PSv3中引入)——它使您的脚本向后与PSv2不兼容…:(我真的不认为稍微减少的字符数有理由破坏向后兼容性。Andy,我已经老了,所以我在某个地方同意你的观点,但是如果一些新脚本不能在PowerShell V2.0中运行,那么不管发生什么情况,真正在PowerShell V2.0中工作的旧脚本都会在PowerShell V3.0中工作。与往常一样,在computer EQ中ipment您需要坚持使用较旧的技术,这不应该阻止技术的进步。@JPBlanc,我只是不认为在这种情况下打破向后兼容性是真正值得的。这在前几天发生在我身上——我在PSv3 ISE中开发了我的脚本(棒极了)部署到带有PSv2的系统,最后不得不弄清楚为什么我的对象上没有名为“…”的成员。IIRC intellisense刚刚给了我,所以我就这么做了。@AndyArismendi这不是V3中唯一的突破性变化(对于$null的每次处理,psd1中的RootModule,早期管道终止,DLR等)。您可以随时启动V3随附的PowerShell v2,以在v2下测试脚本。更让我惊讶的是,我们没有从这个.FWIW中获得.ps3文件扩展名,抛开更改不谈,我喜欢这个新功能。遍历XML(以及一般的嵌套集合)在我看来,这要简单得多。要跟进@SteveKaye的评论,我至少要在上面的优秀链接中添加“为什么”。
“我们添加此功能是为了更容易处理返回一个或多个对象的命令。经验丰富的PowerShell脚本编写者知道他们需要使用@()为了正确处理这种情况,但我们真的认为这不够完美……我们不知道有任何脚本的此更改破坏了脚本,但没有暴露脚本中的潜在问题。”
有趣的功能。