我注意到,当ForEach在数组对象上运行并将输出捕获到新变量时,新变量不是 System.array 类型:
PS D:\Playground> $Arr = 1, 2, 3
PS D:\Playground> $Arr2 = $Arr.ForEach({$_})
PS D:\Playground> $Arr2.Gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Collection`1 System.Object
Run Code Online (Sandbox Code Playgroud)
相反,它是 类型Collection'1。
这是什么类型?它相当于数组吗?
顺便说一句,这与以下内容不同ForEach-Object:
PS D:\Playground> $Arr3 = $($Arr | ForEach-Object { $_ })
PS D:\Playground> $Arr3.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Run Code Online (Sandbox Code Playgroud)
让我以Jeroen Mostert的精彩评论为基础:
数组.ForEach()方法及其姐妹方法.Where(),返回[System.Collections.ObjectModel.Collection[psobject]]集合实例而不是常规 PowerShell 数组 ( [object[]])。
与相关的ForEach-Object/ cmdlet不同,这些方法始终返回一个集合,即使只有一个对象:Where-Object
# .ForEach() method:
# Collection result even with single object.
@(1).ForEach({ $_ }).GetType().Name # -> Collection`1
# ForEach-Object cmdlet:
# Single output object: received as-is.
(@(1) | ForEach { $_ }).GetType().Name # -> Int32
# Two or more output objects: array result (if captured / used in expression)
(1, 2 | ForEach { $_ }).GetType().Name # -> Object[]
Run Code Online (Sandbox Code Playgroud)
注意:这些方法是内部成员的示例,即PowerShell 在所有对象上公开的属性和方法,无论其类型如何(除非存在同名的类型本机成员,该成员优先)。
本质上,此集合类型的行为类似于PowerShell 中的数组(由于实现了[System.Collections.Generic.IList[psobject]]接口):
[0]与数组一样,支持位置索引(例如)。.Add()) 和删除 ( .Remove()) 元素。[psobject](not [object]),通常是不可见的帮助器类型,能够包装任何 .NET 对象,PowerShell(大部分)在幕后使用它。
该.ForEach() 方法与cmdletForEach-Object 对比:
注意:以下内容类似地适用于.Where()vs. Where-Object。
ForEach-Object在命令输出上使用,以便从PowerShell 管道的流式行为中受益(一对一处理,在接收输入时,无需预先收集输入);例如:
Get-ChildItem -Name *.txt| ForEach-Object { "[$_]" }
Run Code Online (Sandbox Code Playgroud)
如果需要更快的处理,请首先用于已经/可以作为一个整体收集在内存中的.ForEach()数组(集合) ;例如:
('foo.txt', 'bar.txt').ForEach({ "[$_]" })
Run Code Online (Sandbox Code Playgroud)
但是,请注意上面讨论的单对象行为和输出集合类型的差异。
有关、、语句以及成员访问枚举的详细并置,请参阅此答案。.ForEach()ForEach-Objectforeach
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |