在官方文档中提到这Length是 的一个别名Count,但是我发现它们的行为不同的一种情况。此外,如果我ForEach用 替换 method ForEach-Object,Length将会发出 3 。有人能解释一下吗?
> (1..3).ForEach({$_}).Length
1
1
1
Run Code Online (Sandbox Code Playgroud)
> (1..3).ForEach({$_}).Count
3
Run Code Online (Sandbox Code Playgroud)
.Length和.Count是彼此的别名,并且是PowerShell 添加到大多数对象中的所谓内在成员(属性) ,以便统一处理标量和集合(有关背景信息,请参阅此答案)。
例外情况是 PowerShell 将其视为集合的类型的对象,即它在管道中自动枚举的对象,其中包括[System.Collections.ObjectModel.Collection[psobject]]数组.ForEach()方法返回的类型的实例。
PowerShell 不会向它所认为的集合的实例添加.Length和属性,因为它假定它们本身.Count具有此类属性(类型本机),并假定可以有效实现(而不是 PowerShell 必须执行枚举和对元素进行计数)。
这是一个合理的假设,通常适用于.Count,但很少适用于.Length(数组 ( ) 是存在并返回元素计数的System.Array一个值得注意的例子)。.Length
因此,通常使用.Count而不是更好.Length。
当您访问.LengthPowerShell 视为集合的类型的实例时,但该类型没有此类类型本机属性,PowerShell 会执行成员访问枚举:
也就是说,它枚举集合并返回元素的.Length属性值。
在您的情况下,由于元素是标量(单个[int]对象),因此它们确实具有内在 .Length属性,在标量的情况下总是返回1。
所以:
(1..3).ForEach({$_}).Length
Run Code Online (Sandbox Code Playgroud)
实际上等同于:
(1..3).ForEach({ $_.Length })
Run Code Online (Sandbox Code Playgroud)
上面解释了 ( 1, 1, 1) 输出。相比之下,[System.Collections.ObjectModel.Collection[psobject]]确实有一个类型本机 .Count属性,它按预期返回元素的计数。
背景资料:
笔记:
只有那些 PowerShell 不考虑集合的类型才能获取内在函数.Count和.Length属性。
相反,被视为集合的类型可能具有或不具有任何此类属性type-natively,并且在缺少 type-native 属性的情况下将执行成员访问枚举。
[Linq.Enumerable]::Range(1,3).Count产量1, 1, 1。PowerShell 认为哪些 .NET 类型是集合(可枚举),因此会在管道中自动枚举:
任何实现IEnumerable/IEnumerable`1 .NET 接口的类型
但以下情况除外,不会自动枚举:
IDictionary/ IDictionary`2,特别包括[hashtable]( @{ ... },作为文字) 及其有序表亲OrderedDictionary( [ordered] @{ ... },作为文字)
XmlNode[xml], ( XmlDocument)的基本类型
字符串( String); 请注意,'foo'.Countis 1(反映字符串被视为标量(单个事物)的内在属性),而'foo'.Lengthis 3(返回字符计数的类型本机属性)。
另外,System.Data.DataTable(它本身不实现IEnumerable,只有它的.Rows属性实现)。
| 归档时间: |
|
| 查看次数: |
560 次 |
| 最近记录: |