Skip to content

Add function in [System.Collections.Generic.List[JiraIssue]] is superseded by hash-table Add when adding a new line to script #21151

Closed

Description

@luc1pop

Prerequisites

Steps to reproduce

I have a powershell script that uses [System.Collections.Generic.List[JiraIssue]] where JiraIssue is its own class. It checks if the list-object is already in memory otherwise it creates it again. The script add one object each time the script is run. You can execute it multiple times without a glitch.
The problem is that if you add an EMPTY row wherever in the script the you will get the error:

 31 |  $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $fa …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
     | Cannot find an overload for "Add" and the argument count: "1".

The script:


class JiraIssue {
    [string]$Jira
    [string]$Desc
    [bool]$Predefined
    JiraIssue([string]$a, [string]$b, [bool]$c)
{
    $this.Jira = $a
    $this.Desc = $b
    $this.Predefined = $c
}

    [string]ToString() {
        return $("($($this.Jira) : $($this.Desc)")
    }
}



#if this exists in memory do not reset it>
if (!$jiraIssues) {
    $jiraIssues = [System.Collections.Generic.List[JiraIssue]]::new()
    Write-host $jiraIssues.GetType()
}

Write-host $jiraIssues.GetType()


$predefJiraIndex= (Get-Date).ToString("yyyy-MM-dd hh:mm:ss")
$jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $false ))

Run this several times and then just add a new line for example on line 32. Then you will get the above error

Expected behavior

PS C:\TestPrograms\scripts> . 'C:\TestPrograms\scripts\testList copy.ps1'
System.Collections.Generic.List`1[JiraIssue]
System.Collections.Generic.List`1[JiraIssue]
PS C:\TestPrograms\scripts> 
PS C:\TestPrograms\scripts> . 'C:\TestPrograms\scripts\testList copy.ps1'
System.Collections.Generic.List`1[JiraIssue]
PS C:\TestPrograms\scripts>

Actual behavior

PS C:\TestPrograms\scripts> . 'C:\TestPrograms\scripts\testList copy.ps1'
System.Collections.Generic.List`1[JiraIssue]
MethodException: C:\TestPrograms\scripts\testList copy.ps1:31:1
Line |
  31 |  $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $fa …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
     | Cannot find an overload for "Add" and the argument count: "1".
PS C:\TestPrograms\scripts>

Error details

PS C:\TestPrograms\scripts> Get-error

Exception             : 
    Type        : System.Management.Automation.MethodException
    ErrorRecord : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Cannot find an overload for "Add" and the argument count: "1".
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : MethodCountCouldNotFindBest
        InvocationInfo        : 
            ScriptLineNumber : 31
            OffsetInLine     : 1
            HistoryId        : 3
            ScriptName       : C:\TestPrograms\scripts\testList copy.ps1
            Line             : $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $false ))

            Statement        : $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $false ))
            PositionMessage  : At C:\TestPrograms\scripts\testList copy.ps1:31 char:1
                               + $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $fa …
                               + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            PSScriptRoot     : C:\TestPrograms\scripts
            PSCommandPath    : C:\TestPrograms\scripts\testList copy.ps1
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, C:\TestPrograms\scripts\testList copy.ps1: line 31
                                at <ScriptBlock>, <No file>: line 1
    TargetSite  : System.Object CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Object, System.Object)
    Message     : Cannot find an overload for "Add" and the argument count: "1".
    Data        : System.Collections.ListDictionaryInternal
    Source      : Anonymously Hosted DynamicMethods Assembly
    HResult     : -2146233087
    StackTrace  :
   at CallSite.Target(Closure, CallSite, Object, Object)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : NotSpecified: (:) [], MethodException
FullyQualifiedErrorId : MethodCountCouldNotFindBest
InvocationInfo        :
    ScriptLineNumber : 31
    OffsetInLine     : 1
    HistoryId        : 3
    ScriptName       : C:\TestPrograms\scripts\testList copy.ps1
    Line             : $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $false ))

    Statement        : $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $false ))
    PositionMessage  : At C:\TestPrograms\scripts\testList copy.ps1:31 char:1
                       + $jiraIssues.Add([JiraIssue]::new($predefJiraIndex.ToString(), '', $fa …
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    PSScriptRoot     : C:\TestPrograms\scripts
    PSCommandPath    : C:\TestPrograms\scripts\testList copy.ps1
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, C:\TestPrograms\scripts\testList copy.ps1: line 31
                        at <ScriptBlock>, <No file>: line 1

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.1
PSEdition                      Core
GitCommitId                    7.4.1
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}       
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Activity

  1. added
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Jan 29, 2024
  2. mklement0 commented on Jan 29, 2024

    @mklement0
    Contributor

    The problem comes down to this:

    • Modifying a class definition - of necessity - creates a new .NET type; even though it has the same name, it is technically distinct.

    • In repeated dot-sourcing invocations, due to the logic of your code, your System.Collections.Generic.List[JiraIssue]] list is only created once, namely based on the initial incarnation of type JiraIssue, which locks this specific incarnation of the type in.

    • When you then modify the class definition, .NET sees a technically different JiraIssue type and refuses to add it to the strongly typed list that expects the initial incarnation.

    You can discover whether two [JiraIssue] incarnations are truly the same type with [JiraIssue].Assembly.FullName;
    it'll show something like PowerShell Class Assembly, Version=1.0.0.2, Culture=neutral, PublicKeyToken=null, with the 2 part getting incremented with every redefinition of the class.

  3. luc1pop commented on Jan 30, 2024

    @luc1pop
    Author

    Ah, thank you for the clarification. Now I understand, closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions