我有一个Powershell脚本,该脚本声明一个类,然后尝试将此类的实例添加到列表中:
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
的类型都是正确的。如何解决此错误?
答案 0 :(得分:5)
这种方式如何?
#do not use this way
#$warnings += $newWarning
#but use this instead
$warnings.Add($newWarning)
答案 1 :(得分:2)
jyao's helpful answer提供了有效的解决方案:
为了将元素追加到您的[System.Collections.Generic.List`1[BuildWarning]]
实例中,请使用其.Add()
方法,而不是PowerShell的+=
运算符。
PowerShell的+=
运算符通常所做的工作是将集合值的LHS视为数组-与特定的LHS集合类型无关-并且“追加”,即,它创建一个(新的)数组,其中包含LHS集合的所有元素,后跟RHS元素。
换句话说:使用+=
忽略特定的LHS集合类型,并始终分配一个(新的)[object[]]
数组,该数组包括LHS集合的元素以及RHS 元素。
鉴于可以合理地保留LHS的特定收集类型,因此这种行为可能令人惊讶-参见this discussion on GitHub。
在您的特定情况下,您会在Windows PowerShell(v5.1以上)中看到一个 bug ,该问题已在PowerShell Core :
如果您尝试类型约束列表变量(在您的情况下为$warnings
),则会出现问题。类型约束是指在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中报告此错误。