MicrosoftDocs / PowerShell-Docs

The official PowerShell documentation sources
https://learn.microsoft.com/powershell
Other
2k stars 1.58k forks source link

Docs needed for 'Why is [pscustomobject] the same as [psobject], even though a distinct [System.Management.Automation.PSCustomObject] type exists?' #3092

Closed joeyaiello closed 3 years ago

joeyaiello commented 6 years ago

This issue was generated because an issue in the PowerShell/PowerShell repository had an issue marked as Documentation Needed and should instead be tracked here in PowerShell-Docs.

The pull request or issue that contains this is located at https://github.com/PowerShell/PowerShell/issues/4344

joeyaiello commented 6 years ago

Not sure if this should go straight into PSCustomObject or PSObject docs, or if we need an about_PSCustomObject topic.

doctordns commented 6 years ago

Given how much use there can be of PSCustomObject, a conceptual help file (About_PSCustomObject) would be useful. The docs for both PSCUstomObject6 and PSObject should also reference the other and explain the differences between the two classes.

sdwheeler commented 3 years ago

@MicrosoftDocs/shiproom-psdocs We need to discuss the need for this documentation.

theJasonHelmick commented 3 years ago

Not sure that we need documentation on this, but I would like to get @JamesWTruher to explain the differences to @sdwheeler and I so we can decide on Docs. I'll comment here after I've spoken to Jim.

sdwheeler commented 3 years ago

Some notes

Both type accelerators are mapped to the same class:

# Even though their names strongly suggest identity, they are different types.
PS> [pscustomobject] -eq [System.Management.Automation.PSCustomObject]
False

PS> [pscustomobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

PS> [psobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

The [pscustomobject] type accelerator was added in PowerShell 4.0 with extra syntactic sugar. There was a common pattern of creating new objects using New-Object and Add-Member to add properties. Casting a hashtable to [pscustomobject] achieves the same result.

[pscustomobject] is not the type that most people expect it to be. You can't use it for type coercion or type comparison, because everything is a PSObject.

# Any object returned by a *command* (as opposed to an expression)
# returns $True for -is [psobject], and therefore also [pscustomobject]
# since both are mapped to PSObject
PS> (Get-Item /) -is [pscustomobject]
True

# Casting anything to [psobject] is a no-op (you get the type of the original object. 
# Therefore, casting anything other than a hashtable to [pscustomobject] results 
# in the same type. 
PS> ([pscustomobject] 666).GetType().Name
Int32

PS> ([PSCustomObject]@{Property = 'Value'}).GetType().FullName
System.Management.Automation.PSCustomObject

PS> ([PSObject]@{Property = 'Value'}).GetType().FullName
System.Collections.Hashtable