Powershell针对集合的每个成员而不是集合的每个成员进行评估
我有以下代码:Powershell针对集合的每个成员而不是集合的每个成员进行评估,powershell,windows-server-2012-r2,powershell-5.0,Powershell,Windows Server 2012 R2,Powershell 5.0,我有以下代码: $a = gci .\Areas -Recurse ($a[0].EnumerateFileSystemInfos()).Count 这是它的输出 PS C:\> ($a[0].EnumerateFileSystemInfos()).Count 1 1 1 1 1 1 为什么??当我运行gm-InputObject$a[0]时,我清楚地看到返回了一个集合 EnumerateFileSystemInfos Method System.Collection
$a = gci .\Areas -Recurse
($a[0].EnumerateFileSystemInfos()).Count
这是它的输出
PS C:\> ($a[0].EnumerateFileSystemInfos()).Count
1
1
1
1
1
1
为什么??当我运行gm-InputObject$a[0]
时,我清楚地看到返回了一个集合
EnumerateFileSystemInfos Method System.Collections.Generic.IEnumerable[System.IO.FileSystemInfo] EnumerateF...
为什么它针对集合的每个成员而不是集合本身来评估.Count
?同样值得注意的是
($a[0].EnumerateFileSystemInfos()).Count()
返回一个错误:
Method invocation failed because [System.IO.FileInfo] does not contain a method named 'Count'.
At line:1 char:1
+ ($a[0].EnumerateFileSystemInfos()).Count()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
这是我对[0][0]澳元的预期,但我不是。发生了什么以及如何检索集合中的项数?
EnumerateFileSystemInfo()
返回一个IEnumerable
,更准确地说,返回一个System.IO.FileSystemMemerableTerator'1
,因此对它的每个查询都返回一个对象。当您通过管道将输出传输到Out Default
时,该cmdlet将检查IEnumerable
是否有更多数据,如果有,则再次查询。这就是为什么会得到一个1的序列,因为枚举表后面的每个对象都是单个对象,而不是数组
您应该改为使用
GetFileSystemInfos()
获取正确的计数,它将返回一个数组。获取集合中的项数$a
:
$a.Count
我不理解增加复杂性和
.NET
/C
方法的必要性。这有什么您需要的吗?1a[0]
不是一个集合,它是一个元素,您引用作为证明的输出是不相关的。2.如果已经递归到每个目录,为什么要使用EnumerateFileSystemInfo?至于后半部分,没有Count()
方法,因此没有任何意义here@wOxxOm证明输出是如何无关的?我正在递归搜索没有文件的目录。@jeroenmoster数组兼容性(内部)。该属性有点硬编码到Powershell中(如果我错了,请更正我的任何人),对于null和empry内容,它返回0;对于任何非数组项或具有1个元素的数组(在许多情况下展开它!),它返回1;对于arrays.FWIW,它返回实际长度,这是一行为(在所有对象上都有.Count
,甚至是一个没有Count
的对象)是(这也碰巧引入了我们在这里看到的展开枚举表上的方法映射)。在此之前,Count
只是集合上的一个合成属性。它使某些场景更明显,但其他场景更令人困惑。更糟糕的是,PowerShell本身包含的文档似乎没有涵盖任何地方。我以什么方式查询IEnumerable?我想在查询之前将其括在括号中调用Count
应该意味着它是从对象而不是其成员请求属性。你不能像使用数组一样一次访问IEnumerable
的所有成员,因此将其括在括号中是不行的。这是有道理的。Powershell会自动展开它,因为它无法与该对象与C#扩展方法非常相似。我确认GetFileSystemInfo()
按预期工作。他想要$a[0]
后面的东西,通常是System.IO.DirectoryInfo
(文件列表中的第一个目录,如果有的话)。但是,不检查方法可能会对他造成长期伤害。