我做了一个非常不幸的错字,花了我相当宝贵的时间:
$errors.Count
Run Code Online (Sandbox Code Playgroud)
0即使存在错误,也会返回" ",因为变量名称应该是单数.这确实有效:
$error.clear() # To ensure a correct repro
Copy-Item asdf fdsa # Will show an error
$error.Count # Will output "1"
Run Code Online (Sandbox Code Playgroud)
但是,我现在想知道为什么$errors.Count给了我任何东西,为什么它给了我" 0".所以我继续做了一些测试,得到了以下结果:
$asdf.Count # Will output "0"
$nrOfEinsteinsInSpace.Count # Will output "0"
$a = 0; $a.Count; # Will output "1"
$b = 2; $a.Count; # Will output "1"
$x = 1,2,3; $x.Count; # Will output "3"
Run Code Online (Sandbox Code Playgroud)
并且收集更多数据以便能够在这里提出一个明智的问题:
$true.Count # Will output "1"
$false.Count # Will output "1"
Run Code Online (Sandbox Code Playgroud)
所以我们有以下不同的情况:
.Count将输出项目数..Count输出"0"..Count输出"1"..Count输出"1".案例2,3和4对我没有任何意义(还).这里发生了什么?这记录在哪里?该.Count物业如何运作?
Jas*_*irk 16
从PowerShell V3开始,属性Count和Length接收到与扩展类型数据(也称为ETS或扩展类型系统)无关的非常特殊的处理.
如果实例具有Count/Length属性,那么一切都像在V1/V2中那样继续工作 - 返回实例的值.
如果实例没有Count/Length属性,从V3开始,而不是那个是错误,你将返回1.如果实例是$ null,你将返回0.如果你已经打开严格模式,你会得到像V2中的错误.
我承认这有点奇怪,但是当cmdlet返回0,1或多个对象时,它解决了一个常见问题.
通常,您将通过管道或foreach语句迭代这些结果.例如:
dir nosuchfile* | % { $_ }
foreach ($item in dir nosuchfile*) { $_ }
Run Code Online (Sandbox Code Playgroud)
在上面的foreach情况中,如果命令没有返回任何值,V2实际上将进入循环.这在V3中已经改变,以更好地满足人们的期望,但这也意味着:
foreach ($item in $null) { $_ }
Run Code Online (Sandbox Code Playgroud)
也永远不会进入循环.
for语句是迭代结果的另一种方式,例如
$results = dir nosuchfile*
for ($i = 0; $i -lt $results.Count; $i++) { $results[$i] }
Run Code Online (Sandbox Code Playgroud)
在这个例子中,$ result中有多少个对象并不重要,循环工作正常.请注意,在V1/V2中,你会写:
$results = @(dir nosuchfile*)
Run Code Online (Sandbox Code Playgroud)
这可以确保$ results是一个数组,但是这种语法很难看,很多人都会忘记它,因此更改以支持Count/Length的方式稍微宽松一些.
为了补充Paul的答案,这可能与扩展类型数据有关.引用文档的相关部分:
扩展类型数据定义Windows PowerShell中对象类型的其他属性和方法("成员").您可以扩展Windows PowerShell支持的任何类型,并使用添加的属性和方法,方法与使用在对象类型上定义的属性相同.
和:
Windows PowerShell会话中有三种扩展类型数据源.Windows PowerShell安装目录中的Types.ps1xml文件会自动加载到每个Windows PowerShell会话中.
如果您打开Types.ps1xml文件(in $pshome),您将在文件的开头看到:
<Type>
<Name>System.Array</Name>
<Members>
<AliasProperty>
<Name>Count</Name>
<ReferencedMemberName>Length</ReferencedMemberName>
</AliasProperty>
</Members>
</Type>
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是,通过提供" .Count"属性,PowerShell假设这是一个数组.