Subexpression operator changes type of array elements?

This topic contains 3 replies, has 3 voices, and was last updated by  Gil Kirkpatrick 2 weeks ago.

  • Author
    Posts
  • #78962

    Gil Kirkpatrick
    Participant

    I've encountered some surprising behavior with the subexpression operator $() changing the type of the result of the subexpression, and I was wondering if anyone can explain it.

    If you create an array of Bytes, GetType() returns Byte[], which is as you would expect. But if you apply the subexpression operator to the byte array, e.g. $($bytes).GetType(), the returned type is an array of Object. Why the change? Then, perhaps even stranger, retrieving the type of one of the elements of the Object array, as in ($bytes)[0].GetType(). returns a Byte value type.

    Anyone know why the subexpression oeprator has this behavior?

    PS C:\> $bytes = [System.Byte[]](1,2)
    PS C:\> $bytes.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Byte[]                                   System.Array
    
    PS C:\> $($bytes).GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    PS C:\> $($bytes)[0].GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Byte                                     System.ValueType
    
    PS C:\> 
    
  • #79252

    Don Jones
    Keymaster

    Hey, Gil!

    Subexpressions were meant for a few specific use cases, where that outcome is essentially desired – as in embedding an expression into a double-quoted string. So some coercion goes on to support those kinds of uses.

  • #79270

    Curtis Smith
    Participant

    Hey Gil,
    I not sure if you were looking for a solution or just looking for understanding as to why it's happening, but what you can do it typecast your subexpression.

    $bytes = [System.Byte[]](1,2)
    
    $bytes.GetType()
    $bytes[0].GetType()
    Write-Host "------------------------------"
    $($bytes).GetType()
    $($bytes)[0].GetType()
    Write-Host "------------------------------"
    ([byte[]]$($bytes)).GetType()
    ([byte[]]$($bytes))[0].GetType()
    Write-Host "------------------------------"

    Results:

    IsPublic IsSerial Name                                     BaseType                                                                                                      
    -------- -------- ----                                     --------                                                                                                      
    True     True     Byte[]                                   System.Array                                                                                                  
    True     True     Byte                                     System.ValueType                                                                                              
    ------------------------------
    True     True     Object[]                                 System.Array                                                                                                  
    True     True     Byte                                     System.ValueType                                                                                              
    ------------------------------
    True     True     Byte[]                                   System.Array                                                                                                  
    True     True     Byte                                     System.ValueType                                                                                              
    ------------------------------
  • #79319

    Gil Kirkpatrick
    Participant

    Thanks Don and Curtis!

    Don, your comment about solving a particular use case makes sense, although the implementation still strikes me as somewhat bizarre. OTOH, that shouldn't surprise anyone familiar with PowerShell. 🙂

    Curtis, as it turns out I could use expression grouping with parens in my situation, so I solved my problem that way. Good to know that forcing the type cast works.

    -gil

You must be logged in to reply to this topic.