PowerShell类型加速器:PSObject vs PSCustomObject
在PowerShell v3.0中引入了PSCustomObject。这就像PowerShell类型加速器:PSObject vs PSCustomObject,powershell,powershell-5.0,psobject,pscustomobject,type-accelerators,Powershell,Powershell 5.0,Psobject,Pscustomobject,Type Accelerators,在PowerShell v3.0中引入了PSCustomObject。这就像PSObject,但更好。在其他改进(例如保留属性顺序)中,简化了从哈希表创建对象: [PSCustomObject]@{one=1; two=2;} 现在看来很明显,这句话: [System.Management.Automation.PSCustomObject]@{one=1; two=2;} 将以同样的方式工作,因为PSCustomObject是完整名称空间+类名的“别名”。相反,我得到了一个错误: 无法将“
PSObject
,但更好。在其他改进(例如保留属性顺序)中,简化了从哈希表创建对象:
[PSCustomObject]@{one=1; two=2;}
现在看来很明显,这句话:
[System.Management.Automation.PSCustomObject]@{one=1; two=2;}
将以同样的方式工作,因为PSCustomObject
是完整名称空间+类名的“别名”。相反,我得到了一个错误:
无法将“System.Collections.Hashtable”类型的“System.Collections.Hashtable”值转换为“System.Management.Automation.PSCustomObject”类型
我列出了两种类型对象的加速器:
[accelerators]::get.GetEnumerator() | where key -Like ps*object
Key Value
--- -----
psobject System.Management.Automation.PSObject
pscustomobject System.Management.Automation.PSObject
发现两者都引用相同的PSObject
类-这意味着使用加速器可以做很多其他事情,而不仅仅是缩短代码
关于这个问题,我的问题是:
查看静态方法:
PS C:\> [PSCustomObject] | gm -Static -MemberType Method
TypeName: System.Management.Automation.PSObject
Name MemberType Definition
---- ---------- ----------
AsPSObject Method static psobject AsPSObject(System.Object obj)
Equals Method static bool Equals(System.Object objA, System.Object objB)
new Method psobject new(), psobject new(System.Object obj)
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object o...
PS C:\> [System.Management.Automation.PSCustomObject] | gm -Static -MemberType Method
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method static bool Equals(System.Object objA, System.Object objB)
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object o...
类型加速器添加了两个新的静态方法。我怀疑它使用了其中一个作为构造函数。[PSObject]和[PSCustomObject]是同一类型的别名-System.Management.Automation.PSObject。我不能说这是一个很好的理由,但它至少暗示了两个不同的目的,也许这就足够了 System.Management.Automation.PSObject用于包装对象。引入它是为了在PowerShell包装的任何对象上提供公共反射api-.Net、WMI、COM、ADSI或简单属性包 System.Management.Automation.PSCustomObject只是一个实现细节。创建PSObject时,PSObject必须包装某些内容。对于属性包,包装的对象是System.Management.Automation.PSCustomObject.SelfInstance(内部成员)。此实例对PowerShell的正常使用是隐藏的,观察它的唯一方法是使用反射 在PowerShell中以多种方式创建属性包:
$o1 = [pscustomobject]@{Prop1 = 42}
$o2 = new-object psobject -Property @{Prop1 = 42 }
上面的$o1和$o2都是PSObject的实例,PSObject将包装PSCustomObject.SelfInstance。PowerShell内部使用PSCustomObject.SelfInstance来区分简单属性包和包装任何其他对象之间的区别。如果您反编译
System.Management.Automation.Language.Compiler.VisitConvertExpression
,则可以看到对三种类型名称有特殊处理:ordered
,PSCustomObject
和ref
。你好,Jason。Get Member
和.GetType()
都将$o1和$o2作为PSCustomObject而不是PSObject的实例进行报告。但是,如果我将第三个对象创建为$o3=[PSObject]@{Prop1=42}
,则该对象不同。我的观点是,上面的答案令人困惑,因为在powershell[PSObject]
和[pscustomobject]
当然不要这样做。是的,这有点让人困惑,部分是我的错,部分是设计。我错过了调用GetType()作为查看pscustomobject的一种方式。从V3开始,对[pscustomobject]的强制转换在解析器中被特别处理,在此之前,它将等同于对[psobject]的强制转换但是,底线是类型(和单例实例)System.Management.Automation.PSCustomObject是一个实现细节。如果操作数是散列文字,则转换[PSCustomObject]很有用,否则它相当于[psobject]转换。@JasonShirk如果内存可用,则使用[PSCustomObject]
转换(n v3或更高版本)在某些受限语言模式下可能会失败,而其他一些方法(newobject
?Select Object
?)会在相同的上下文中工作。我现在不记得细节了,因为我几年前发现了(困难的方法)。