Невозможно добавить экземпляр моего класса в список <мой класс> - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть скрипт 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 являются правильными. Как исправить эту ошибку?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

полезный ответ Цзяо предоставляет эффективное решение:

Чтобы добавить элементы к вашему экземпляру [System.Collections.Generic.List`1[BuildWarning]], используйте его метод .Add(), а не оператор += PowerShell.

Оператор += PowerShell , обычно , обычно обрабатывает LHS со значением коллекции как массив 1016 * - независимо от конкретного типа коллекции LHS - и «добавляет» к этому массиву то есть он создает (новый) массив, содержащий все элементы коллекции LHS, за которыми следует элемент (ы) RHS.

Другими словами: с использованием += игнорирует определенный тип коллекции LHS и неизменно назначает (новый) массив [object[]], содержащий элементы коллекции LHS плюс элемент RHS ( s).

Такое поведение может быть удивительным, учитывая, что разумно ожидать сохранения определенного типа сбора LHS - см. это обсуждение на GitHub .

В вашем конкретном случае вы видите ошибку в Windows PowerShell начиная с версии 5.1 , которая была исправлена ​​в 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 .

0 голосов
/ 01 сентября 2018

Как насчет этого?

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

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