PowerShell 将对象附加到变量列表

PowerShell append objects to variable list

刚接触 PowerShell,想了解如何将对象附加到变量列表。以下是错误信息:

Method invocation failed because [System.IO.FileInfo] does not contain a method named 'op_Addition'.
At C:\Users\Username\Desktop\Sandbox\New folder\BoxProjectFiles.ps1:117 char:4
+             $MechDWGFile += $file
+             ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

和代码:

LogWrite "`n-------------Mechanical Drawing(s)------------"
foreach ($file in $MechDWGList)
{
    # Where the file name contains one of these filters
    foreach($filter in $MechDWGFilterList)
    {
        if($file.Name -like $filter)
        {
            $MechDWGFile += $file # this is where the error is happening, so I know it is probably something simple
            LogWrite $file.FullName
        }
    }
}

正在使用 PowerShell 5.1 和 Windows10 OS。

有人可以帮助我理解我的语法有什么问题吗?

根据错误消息,$MechDWGFile 已经包含一个 [FileInfo] 对象 - Get-ItemGet-ChildItem 返回的对象类型。

+= 运算符在 PowerShell 中被 重载 ,这意味着它的行为取决于您在left-hand 面 - 在本例中 $MechDWGFile 包含一个 [FileInfo] 对象。

$file 也包含这样一个对象,但是 [FileInfo] + [FileInfo] 没有任何意义,这就是您看到错误的原因。

要使 += 运算符起作用,您需要使用 @() 数组子表达式运算符创建一个数组:

$MechDWGFile = @()

# ...

# This now works
$MechDWGFile += $file

如果您已使用 Get-ItemGet-ChildItem 的输出初始化 $MechDWGFile,只需将现有管道嵌套在 @():

# `Get-ChildItem |Select -First 1` will only output 1 object, 
# but the @(...) makes PowerShell treat it as a 1-item array
# which in turn allows you to use `+=` later
$MechDWGFile = @(Get-ChildItem -Recurse -File |Select -First 1)

关于 PowerShell 中数组的一个重要警告 — 它们 不可变.

虽然您可以使用重载的 += 运算符将元素“添加”到 PowerShell 中的数组,但它实际上所做的是创建一个 新数组 ,其元素为第一个操作数和第二个操作数合并。

这可能更多是个人喜好,但当我计划循环遍历一堆项目来填充数组时,我会改用 [ArrayList]。 ArrayLists 在设计上是可变的。为什么这不是 PowerShell 中的默认设置,我不知道。

向现有数组添加新元素:

$Array1 = Get-ChildItem -Path 'C:\'
$Array2 = @()

# Add only the directories to our second array
foreach ($Item in $Array1) {
    if ($Item.PSIsContainer) {
        $Array2 += $Item    # This creates a new array every time
    }
}

$Array2

向现有元素添加新元素 [ArrayList]:

$Array1 = Get-ChildItem -Path 'C:\'
$Array2 = [System.Collections.ArrayList]@()

# Add only the directories to our ArrayList
foreach ($Item in $Array1) {
    if ($Item.PSIsContainer) {
        $null = $Array2.Add($Item)    # This does not create a new object each time.

        # The $null= prepend is because [ArrayList].Add() will output the ID of the
        #   last element added, so we assign that to null, keeping our console clean.
    }
}

$Array2

旁注: 正如 Mathias 所说,您的变量 $MechDWGFile 可能尚未初始化为数组,这就是 += 重载运算符的原因没有工作,而是抛出了一个错误。