Cannot add an instance of my class to the list
Cannot add an instance of my class to the list<my class>
I have a Powershell script that declares a class and then tries to add an instance of this class to a list:
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)
" + Project + "
"@
[System.Collections.Generic.List``1[BuildWarning]] $warnings = New-Object "System.Collections.Generic.List``1[BuildWarning]"
[BuildWarning] $newWarning = New-Object BuildWarning("", "", "", "")
$warnings += $newWarning
At the last line I get an error:
I cannot figure out what the problem is. The type checks show that types of both $warnings and $newWarning are correct. How to fix this error?
$warnings
$newWarning
2 Answers
2
jyao's helpful answer provides an effective solution:
In order to append elements to your [System.Collections.Generic.List`1[BuildWarning]] instance, use its .Add() method, not PowerShell's += operator.
[System.Collections.Generic.List`1[BuildWarning]]
.Add()
+=
What PowerShell's += operator normally does is to treat a collection-valued LHS as an array - irrespective of the specific LHS collection type - and "appends" to that array, i.e., it creates a (new) array containing all elements of the LHS collection followed by the RHS element(s).
+=
In other words: using += ignores the specific LHS collection type and invariably assigns a (new) [object] array comprising the LHS collection's elements plus the RHS element(s).
+=
[object]
This behavior may be surprising, given that it's reasonable to expect the specific collection type of the LHS to be preserved - see this discussion on GitHub.
In your specific case, you're seeing a bug in Windows PowerShell as of v5.1, which has been fixed in PowerShell Core:
The problem arises if you try to type-constrain the list variable, $warnings in your case. Type-constraining means placing a type (cast) before the LHS variable name, which locks the variable's type in, so that subsequent assignments must be of the same or a compatible type.
$warnings
To provide a simple example:
$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"
I encourage you to report this bug in the Windows PowerShell UserVoice forum.
How about this way?
#do not use this way
#$warnings += $newWarning
#but use this instead
$warnings.Add($newWarning)
It does fix the error. Thank you. But can you explain the reason?
– Maxim Gritsenko
Sep 1 at 5:52
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Glad to hear it was helpful, @MaximGritsenko; my pleasure.
– mklement0
Sep 2 at 12:05