Lot*_*i11 2 arrays powershell member-enumeration
我正在编写一个遍历目录的递归函数,并复制其中的每个文件和文件夹.我在函数中的第一个检查是查看传入的路径是否有子节点.为了找到这个,我使用以下方法:
[array]$arrExclude = @("Extras")
Function USBCopy
{
Param ([string]$strPath, [string]$strDestinationPath)
try
{
$pathChildren = Get-ChildItem -Path $strPath
if($pathChildren.Length -gt 0)
{
foreach($child in $pathChildren)
{
if($arrExclude -notcontains $child)
{
$strPathChild = "$strPath\$child"
$strDestinationPathChild = "$strDestinationPath\$child"
Copy-Item $strPathChild -Destination $strDestinationPathChild
USBCopy $strPathChild $strDestinationPathChild
}
}
}
}
catch
{
Write-Error ("Error running USBCopy: " + $Error[0].Exception.Message)
}
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,我的函数可以工作,但我的代码会说当一个目录实际上有一个文件时它是空的.当我调试我的函数时,变量会说该文件夹有子项但变量的长度为0.任何人都知道如何解决这个问题?
PetSerAl,在很多次之前,已经在问题的简短评论中提供了关键指针(并且他也帮助改进了这个答案):
$pathChildren = @(Get-ChildItem -Path $strPath)
Run Code Online (Sandbox Code Playgroud)
使用@(...)中,阵列子表达式运算符,可以确保,无论封闭命令输出被视为一个阵列,即使只有1目的是输出,以便.Length被保证是阵列的.Length属性.
但是,在PSv3 +中,访问.Count而不是.Length像WillPanic的有用答案一样,也可以使用 - 见下文.
如果没有@(...),结果可能是单个对象,因为PowerShell会自动解包仅包含1个对象的输出集合,该集合仅生成一个对象,这意味着以下内容:
到PSv2:
.Length属性,则返回其值.[System.IO.FileInfo]实例)(如果该目录只包含1个文件且没有子目录,则隐藏的项目除外),则这是真的.[System.IO.FileInfo]实例的.Length属性以字节为单位返回文件的大小.值为0暗示空文件.[System.IO.DirectoryInfo]实例,.Length将返回$null,因为这样的实例没有.Length属性.)在PSv3 +,解决方法是不再严格需要的,如果使用.Count,因为可以治疗甚至一个标量(单个对象),就好像它是一个阵列,其中隐式 .Length/.Count[1]
的属性和能力指数为(例如,
<scalar>[0]),但有一些警告:
如果有效Set-StrictMode -Version 2或更高有效,则访问.Length和.Count实际上不存在于标量上的属性会导致错误.
然而,这种行为非常不幸,因为这些属性应该被认为是隐含存在的- 如果您同意,请在此GitHub问题中听取您的意见.
如果标本身具有这样的属性作为.Length或.Count或支持索引,即优先 -这就是为什么.Count要在这种情况下使用(如说明,[System.IO.FileInfo]实例有.Length物业报告以字节为单位的文件大小); 见下面的例子.
使用@(...)避免这种冲突,因为结果总是一个数组.
成员枚举是统一的补充方面,它允许您在集合级别应用集合中包含的项的成员(属性或方法),在这种情况下,成员可以隐式访问集合中的每个项目,并且结果值以数组形式返回; 见下面的例子.
要解决与成员枚举的名称冲突,需要采用不同的方法 - 请参阅我的这个答案.
PS> (666).Length
1 # Scalar 666 was implicitly treated as a collection of length 1
PS> (666).Count
1 # Ditto - ** .Count is preferable, because it less often means something else **
# Caveat: A *string* scalar has a native .Length property
PS> ('666').Length; ('666').Count
3 # .Length: The string types's native property: the number of *characters*
1 # .Count: PowerShell's implicit collection handling: 1 *element*
PS> (666)[0]; (666)[-1]
666 # Index [0] always yields the scalar itself.
666 # Ditto for [-1], the *last* element.
# Member enumeration example: get the .Day property value from each
# [datetime] instance stored in an array.
PS> ((Get-Date), (Get-Date).AddDays(-1)).Day
20
19
Run Code Online (Sandbox Code Playgroud)
[1]正如PetSerAl指出的那样,直到PSv5.1,数组的.Count属性是一个别名属性.Length,由PowerShell的ETS(扩展类型系统 - 参见Get-Help about_Types.ps1xml.但是,这个别名属性自PSv3以来并没有真正需要已实现的.NET接口类型成员也被PowerShell公开,提供对数组类型ICollection.Count属性的访问.因此v6将不再具有别名属性,此时.Count将直接访问ICollection.Count- 请参阅此GitHub问题.
请注意,PowerShell魔术仍然涉及到然而,它涉及调用.Count"假"数组(标量).
| 归档时间: |
|
| 查看次数: |
1225 次 |
| 最近记录: |