about_PSCustomObject
简短说明
介绍了 [psobject]
与 [pscustomobject]
类型加速器之间的差异。
长说明
[pscustomobject]
类型加速器是在 PowerShell 3.0 中添加的。
在添加此类型加速器之前,创建具有成员属性和值的对象比较复杂。 最初,必须使用 New-Object
来创建对象并使用 Add-Member
来添加属性。 例如:
PS> $object1 = New-Object -TypeName PSObject
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name one -Value 1
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name two -Value 2
PS> $object1 | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
two NoteProperty int two=2
PS> $object1
one two
--- ---
1 2
后来,可以使用 New-Object
的 Property 参数传递包含成员和值的哈希表。 例如:
PS> $object2 = New-Object -TypeName PSObject -Property @{one=1; two=2}
PS> $object2 | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
two NoteProperty int two=2
PS> $object2
one two
--- ---
1 2
从 PowerShell 3.0 开始,将哈希表强制转换为 [pscustomobject]
可实现相同的结果。
PS> $object3 = [pscustomobject]@{one=1; two=2}
PS> $object3 | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
two NoteProperty int two=2
PS> $object3
one two
--- ---
1 2
PSObject 类型对象按照成员添加到对象的顺序维护其成员列表。 尽管哈希表对象不能保证键值对的顺序,但将文本哈希表强制转换为 [pscustomobject]
可保持该顺序。
哈希表必须是文本。 如果将哈希表括在括号中,或者强制转换包含哈希表的变量,则不能保证顺序被保留。
$hash = @{
Name = "Server30"
System = "Server Core"
PSVersion = "4.0"
}
$Asset = [pscustomobject]$hash
$Asset
System Name PSVersion
------ ---- ---------
Server Core Server30 4.0
了解类型加速器
[psobject]
和 [pscustomobject]
是类型加速器。
有关详细信息,请参阅 about_Type_Accelerators。
尽管你可能认为 [pscustomobject]
应该映射到 System.Management.Automation.PSCustomObject,但这两个类型不同。
PS> [pscustomobject] -eq [System.Management.Automation.PSCustomObject]
False
这两个类型加速器都映射到同一个类,即 PSObject:
PS> [pscustomobject]
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True PSObject System.Object
PS> [psobject]
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True PSObject System.Object
将 [pscustomobject]
类型加速器添加到 PowerShell 时,它包含了额外的代码来处理哈希表到 PSObject 类型的转换。 仅当创建新对象时,才会调用此额外代码。
因此,不能将 [pscustomobject]
用于类型强制转换或类型比较,因为所有对象都被视为 PSObject 类型。
例如,使用 -is
运算符检查 cmdlet 返回的对象是否为 [pscustomobject]
与将其与 [psobject]
进行比较相同。
PS> (Get-Item /) -is [pscustomobject]
True
PS> (Get-Item /) -is [psobject]
True
将任何对象强制转换为 [psobject]
将获得原始对象的类型。 因此,将除哈希表以外的任何内容强制转换为 [pscustomobject]
会导致同一类型。
PS> ([psobject]@{Property = 'Value'}).GetType().FullName
System.Collections.Hashtable
PS> ([pscustomobject]123).GetType().Name
Int32
PS> ([pscustomobject]@{Property = 'Value'}).GetType().FullName
System.Management.Automation.PSCustomObject
虽然将对象强制转换为 [psobject]
似乎对类型没有影响,但 PowerShell 会在对象周围添加一个不可见的 [psobject]
包装器。 这会产生微小的副作用。
被包装的对象将匹配其原始类型和
[psobject]
类型。PS> 1 -is [Int32] True PS> 1 -is [psobject] False PS> ([psobject] 1) -is [Int32] True PS> ([psobject] 1) -is [psobject] True
格式运算符 (
-f
) 无法识别由[psobject]
包装的数组。PS> '{0} {1}' -f (1, 2) 1 2 PS> '{0} {1}' -f ([psobject] (1, 2)) Error formatting a string: Index (zero based) must be greater than or equal to zero and less than the size of the argument list..
说明
在 Windows PowerShell 中,通过将 Hashtable 强制转换为 [pscustomobject]
创建的对象没有 Length 或 Count 属性。
尝试访问这些成员将返回 $null
。
例如:
PS> $object = [PSCustomObject]@{key = 'value'}
PS> $object
key
---
value
PS> $object.Count
PS> $object.Length
从 PowerShell 6 开始,通过将 Hashtable 强制转换为 [pscustomobject]
创建的对象的 Length 和 Count 属性始终有一个值:1
。
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈