无法将我的 class 的实例添加到列表 <my class>

Cannot add an instance of my class to the list<my class>

我有一个 Powershell 脚本,它声明了一个 class,然后尝试将此 class 的一个实例添加到列表中:

Add-Type -TypeDefinition @"
using System.Text.RegularExpressions;
public class BuildWarning
{
    public string Solution { get; private set; }
    public string Project { get; private set; }
    public string WarningMessage { get; private set; }
    public string WarningCode { get; private set; }
    public string Key { get; private set; }
    public bool IsNew { get; set; }
    private static readonly Regex warningMessageKeyRegex = new Regex(@"^(?<before>.*)\([0-9,]+\)(?<after>: warning .*)$");
    public BuildWarning(string solution, string project, string warningMessage, string warningCode)
    {
        Solution = solution;
        Project = project;
        WarningMessage = warningMessage;
        WarningCode = warningCode;
        var match = warningMessageKeyRegex.Match(WarningMessage);
        Key = Solution + "|" + Project + "|" + match.Groups["before"].Value + match.Groups["after"].Value;
    }
}
"@

[System.Collections.Generic.List``1[BuildWarning]] $warnings = New-Object "System.Collections.Generic.List``1[BuildWarning]"

[BuildWarning] $newWarning = New-Object BuildWarning("", "", "", "")

$warnings += $newWarning

在最后一行出现错误:

Cannot convert the "System.Object[]" value of type "System.Object[]" to type
"BuildWarning".
At C:\development\temp\BuildWarningReportGenerator.ps1:93 char:17
+                 $warnings += $newWarning
+                 ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

我不知道问题出在哪里。类型检查显示 $warnings$newWarning 的类型都是正确的。如何修复此错误?

这样怎么样?

#do not use this way
#$warnings += $newWarning

#but use this instead
$warnings.Add($newWarning)

提供了一个有效的解决方案:

为了 将元素附加到您的 [System.Collections.Generic.List`1[BuildWarning]] 实例,请使用它的 .Add() 方法,而不是 PowerShell 的 += 运算符。

PowerShell 的 += 运算符 通常 所做的是将集合值 LHS 视为 数组 - 无论特定的 LHS 集合类型 - 和 "appends" 该数组,即它创建一个(新)数组,其中包含 LHS 集合的所有元素,后跟 RHS 元素。

换句话说:使用+= 忽略特定的LHS集合类型并且总是分配一个(新的)[object[]]数组包含LHS 集合的元素加上 RHS 元素。

这种行为可能令人惊讶,因为可以合理地期望保留 LHS 的特定集合类型 - 请参阅 this discussion on GitHub

在您的具体情况下,您在 Windows PowerShell v5.1 中看到一个 错误,它已在 PowerShell Core:

中修复

如果您尝试类型约束列表变量,问题就会出现。类型约束是指在 LHS 变量名之前放置一个类型(强制转换),这会锁定变量的类型,以便后续赋值必须是相同或兼容的类型。

举个简单的例子:

$list = New-Object 'System.Collections.Generic.List[int]'
$list += 1  # OK - $list is not type-constrained
Write-Verbose -Verbose "Unconstrained `$list 'extended': $list"


# Type-constrained $list
[System.Collections.Generic.List[int]] $list = New-Object 'System.Collections.Generic.List[int]'
$list += 1  # !! BREAKS, due to the bug
Write-Verbose -Verbose "Type-constrained `$list 'extended': $list"

我鼓励您在 Windows PowerShell UserVoice forum 中报告此错误。