Skip to content

Why is ([System.Collections.ObjectModel.Collection[psobject]]1)[0] a string? #7154

Closed

Description

@alx9r

I've been using this conversion to pass objects to PowerShell.Invoke() like this:

PowerShell.Invoke([System.Collections.ObjectModel.Collection[psobject]]$obj)

I'm puzzled by this conversion from [int32] to [string].

Steps to reproduce

([System.Collections.ObjectModel.Collection[psobject]]1)[0].GetType().Name

Expected behavior

I expected 1 to remain an [int32].

int32

Actual behavior

1 is converted to a [string]

string

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.1.0-preview.688
PSEdition                      Core
GitCommitId                    v6.1.0-preview.688
OS                             Microsoft Windows 6.3.9600
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Activity

  1. added
    WG-Enginecore PowerShell engine, interpreter, and runtime
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Jun 23, 2018
  2. mklement0 commented on Jun 24, 2018

    @mklement0
    Contributor

    I have no explanation, but 2 quick additional observations:

    • It only happens when you cast a scalar; ([System.Collections.ObjectModel.Collection[psobject]] (, 1))[0].GetType().Name yields Int32, as expected.

    • It also happens with [System.Collections.Generic.List[object]]; by contrast:

      • casting a scalar to [System.Collections.ArrayList] fails,
      • but works correctly with [object[]]
  3. alx9r commented on Jun 24, 2018

    @alx9r
    Author

    It looks like { Write-Object $obj -NoEnumerate }.Invoke() is a more reliable way to convert to [Collection[psobject]]. Or at least is was before #2038, and (hopefully) will be again once those issues are corrected. In the meantime Write-Output2 from 6451(comment) seems to work.

  4. mklement0 commented on Jun 24, 2018

    @mklement0
    Contributor

    If you're not concerned about the intermediate, transient [object[]] array that is invariably constructed, you can also do [System.Collections.Generic.List[object]] @($obj)

  5. PetSerAl commented on Jun 24, 2018

    @PetSerAl
    Contributor

    It seems that given conversion covered here:

    converter = LanguagePrimitives.ConvertNumericIConvertible;

    And ConvertNumericIConvertible specifically do conversion thru string:
    // If the original object was a number, then try and do a conversion on the string
    // equivalent of that number...

  6. alx9r commented on Jun 24, 2018

    @alx9r
    Author
     // If the original object was a number, then try and do a conversion on the string 
     // equivalent of that number... 
    

    Interesting. That is clearly deliberate. But why do that?

  7. lzybkr commented on Jun 25, 2018

    @lzybkr
    Contributor

    I'm not sure this really is deliberate, I think another explanation is that this is just a symptom of PowerShell being especially permissive with conversions.

    Based on this check:

    it feels like an oversight to have allowed the conversion to collections other than array.

  8. KnowledgeNerd commented on Jun 3, 2022

    @KnowledgeNerd

    I feel like this isn't purposeful and some if going on weird here. This is a PowerShell code showing the same and other weird issues.

    Code

    $orig_notworking = ([System.Collections.ObjectModel.Collection[psobject]]1)
    echo "orig_notworking - $($orig_notworking[0].GetType().Name)"

    $orig_working = (New-Object -TypeName System.Collections.ObjectModel.Collection[psobject])
    $orig_working.Add([psobject]1)
    echo "orig_working - $($orig_working[0].GetType().Name)"

    Removed a incorrect example showing a different error. Was my fault.

    #Shows that the original creation of the psobject is equivalent
    echo '(New-Object -TypeName PSObject -ArgumentList @(1)) -eq [psobject]1)'
    (New-Object -TypeName PSObject -ArgumentList @(1)) -eq [psobject]1

    $notworking = ([System.Collections.ObjectModel.Collection[psobject]](New-Object -TypeName PSObject -ArgumentList @(1)))
    echo "notworking - $($notworking[0].GetType().Name)"

    $working = (New-Object -TypeName System.Collections.ObjectModel.Collection[psobject])
    $working.Add((New-Object -TypeName PSObject -ArgumentList @(1)))
    echo "working - $($working[0].GetType().Name)"

    Output

    orig_notworking - String
    orig_working - Int32
    #Removed output from my mistake code above from this list
    (New-Object -TypeName PSObject -ArgumentList @(1)) -eq [psobject]1)
    True
    notworking - String
    working - Int32

    Sorry for the terrible code and the old post revival, but I got interested. It feels like the constructor and/or assignment operator is doing something weird.

  9. PetSerAl commented on Jun 3, 2022

    @PetSerAl
    Contributor

    KnowledgeNerd, you assign to $orig_work_but_not_working the result of calling Add, which is void, and not the collection.

  10. KnowledgeNerd commented on Jun 3, 2022

    @KnowledgeNerd

    Ohhh nice catch. I'll remove that one example. Still interesting that the add doesn't convert the int to string but instantiating it using the constructor with initial values does.

  11. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  12. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  13. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  14. KnowledgeNerd commented on Nov 17, 2023

    @KnowledgeNerd

    Gotta say I revisited this again and was appalled at my code... But I still think something is weird.

    Check out this ~slightly~ better and cleaner code to see what's going on:

    $testobj = New-Object -TypeName PSObject -ArgumentList @(1)
    $testobj2 = [psobject]1
    $testobj3 = 1
    
    
    $test = New-Object -TypeName System.Collections.ObjectModel.Collection[psobject]
    $test.Add($testobj)
    $test[0].gettype().name
    
    $test2 = [System.Collections.ObjectModel.Collection[psobject]]($testobj)
    $test2[0].gettype().name
    
    
    $test3 = New-Object -TypeName System.Collections.ObjectModel.Collection[psobject]
    $test3.Add($testobj2)
    $test3[0].gettype().name
    
    $test4 = [System.Collections.ObjectModel.Collection[psobject]]($testobj2)
    $test4[0].gettype().name
    
    
    $test5 = New-Object -TypeName System.Collections.ObjectModel.Collection[psobject]
    $test5.Add($testobj3)
    $test5[0].gettype().name
    
    $test6 = [System.Collections.ObjectModel.Collection[psobject]]($testobj3)
    $test6[0].gettype().name
    

    Output

    Int32
    String
    
    Int32
    String
    
    Int32
    String
    
  15. microsoft-github-policy-service commented on Nov 25, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

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

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions