Powershell PSObject、哈希表和PSCustomObject之间的差异
有人能解释一下细节吗?如果我使用Powershell PSObject、哈希表和PSCustomObject之间的差异,powershell,powershell-3.0,psobject,Powershell,Powershell 3.0,Psobject,有人能解释一下细节吗?如果我使用 $var = [PSObject]@{a=1;b=2;c=3} 然后我使用getType()PowerShell查找它的类型,PowerShell告诉我它属于哈希表类型 当使用(别名gm)检查对象时,很明显已经创建了哈希表,因为它具有键和值属性。那么,“普通”哈希表有什么区别呢 另外,使用PSCustomObject有什么好处?当用这样的东西创建一个 $var = [PSCustomObject]@{a=1;b=2;c=3} 对我来说唯一可见的区别是PSCu
$var = [PSObject]@{a=1;b=2;c=3}
然后我使用getType()
PowerShell查找它的类型,PowerShell告诉我它属于哈希表类型
当使用(别名gm
)检查对象时,很明显已经创建了哈希表,因为它具有键
和值
属性。那么,“普通”哈希表有什么区别呢
另外,使用PSCustomObject有什么好处?当用这样的东西创建一个
$var = [PSCustomObject]@{a=1;b=2;c=3}
对我来说唯一可见的区别是PSCustomObject的不同数据类型。另外,使用gm
进行检查,发现现在每个键都已添加为NoteProperty对象,而不是键和值属性
但是我有什么优势呢?我可以使用它的键访问我的值,就像在哈希表中一样。我可以在PSCustomObject中存储多个简单的键值对(例如键对象对),就像在哈希表中一样。那么优势是什么呢?有什么重要的区别吗?我认为你将看到的最大区别是性能。看看这篇博文: 作者运行了以下代码:
$numberofobjects = 1000
$objects = (0..$numberofobjects) |% {
New-Object psobject -Property @{'Name'="object$_";'Path'="Path$_"}
}
$lookupobjects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Path'="Path$_";'Share'="Share$_"}
}
$method1 = {
foreach ($object in $objects) {
$object | Add-Member NoteProperty -Name Share -Value ($lookupobjects | ?{$_.Path -eq $object.Path} | select -First 1 -ExpandProperty share)
}
}
Measure-Command $method1 | select totalseconds
$objects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Name'="object$_";'Path'="Path$_"}
}
$lookupobjects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Path'="Path$_";'Share'="Share$_"}
}
$method2 = {
$hash = @{}
foreach ($obj in $lookupobjects) {
$hash.($obj.Path) = $obj.share
}
foreach ($object in $objects) {
$object |Add-Member NoteProperty -Name Share -Value ($hash.($object.path)).share
}
}
Measure-Command $method2 | select totalseconds
@{name='a';num=1},@{name='b';num=2} |
% { [PSCustomObject]$_ }
# OR
@{name='a';num=1},@{name='b';num=2} |
% { New-Object PSObject -Property $_ }
<#
Outputs:
name num
---- ---
a 1
b 2
#>
博客作者的输出:
TotalSeconds
------------
167.8825285
0.7459279
他对代码结果的评论如下:
当你把它们放在一起时,你可以看到速度上的差异。在我的计算机上,object方法需要167秒,而hash table方法需要不到一秒的时间来构建哈希表,然后进行查找
以下是一些其他更微妙的好处:
我认为PSObject的一个优点是可以使用它创建自定义方法 比如说,
$o = New-Object PSObject -Property @{
"value"=9
}
Add-Member -MemberType ScriptMethod -Name "Sqrt" -Value {
echo "the square root of $($this.value) is $([Math]::Round([Math]::Sqrt($this.value),2))"
} -inputObject $o
$o.Sqrt()
您可以使用它来控制PSObject属性的排序顺序(请参见)当您需要它们的集合时,可以使用
[PSCustomObject]
而不是哈希表。以下是说明如何处理这些问题的区别:
$Hash = 1..10 | %{ @{Name="Object $_" ; Index=$_ ; Squared = $_*$_} }
$Custom = 1..10 | %{[PSCustomObject] @{Name="Object $_" ; Index=$_ ; Squared = $_*$_} }
$Hash | Format-Table -AutoSize
$Custom | Format-Table -AutoSize
$Hash | Export-Csv .\Hash.csv -NoTypeInformation
$Custom | Export-Csv .\CustomObject.csv -NoTypeInformation
格式表
将为$Hash
产生以下结果:
Name Value
---- -----
Name Object 1
Squared 1
Index 1
Name Object 2
Squared 4
Index 2
Name Object 3
Squared 9
...
以及$CustomObject
的以下内容:
Name Index Squared
---- ----- -------
Object 1 1 1
Object 2 2 4
Object 3 3 9
Object 4 4 16
Object 5 5 25
...
同样的事情发生在导出Csv时,因此使用[PSCustomObject]
而不仅仅是普通的哈希表的原因是我想创建一个文件夹。如果我使用PSObject,你可以通过
看看它
PS>[PSObject]@{Path='foo';Type='directory'}
名称值
---- -----
路富
类型目录
但是PSCustomObject看起来正确
PS>[PSCustomObject]@{Path='foo';Type='directory'}
路径类型
---- ----
foo目录
然后我可以用管道输送这个物体
[PSCustomObject]@{Path='foo';Type='directory'}新项
:
包装对象,以提供可用成员的备选视图以及扩展这些成员的方法。成员可以是方法、属性、参数化属性等
换句话说,PSObject
是一个对象,您可以在创建它之后向其添加方法和属性
:
哈希表,也称为字典或关联数组,是一种紧凑的数据结构,存储一个或多个键/值对
哈希表经常被使用,因为它们对于查找和检索数据非常有效
您可以像使用哈希表一样使用PSObject
,因为PowerShell允许您向PSObjects
添加属性,但您不应该这样做,因为您将无法访问哈希表
的特定功能,例如键
和值
属性。此外,可能会有性能成本和额外的内存使用
:
当使用PSObject的构造函数(不带参数)时,用作占位符BaseObject
这对我来说并不清楚,但从中似乎更清楚:
[PSCustomObject]是类型加速器。它构造一个PSObject,但这样做的方式会导致哈希表键成为属性。PSCustomObject本身不是对象类型–它是一个流程快捷方式。。。PSCustomObject是在没有构造函数参数的情况下调用PSObject时使用的占位符
关于您的代码,@{a=1;b=2;c=3}
是一个哈希表
[PSObject]@{a=1;b=2;c=3}
不会将哈希表
转换为PSObject
或生成错误。对象仍然是一个哈希表
。但是,[PSCustomObject]@{a=1;b=2;c=3}
将哈希表
转换为PSObject
。我找不到说明为什么会发生这种情况的文档
如果要将哈希表
转换为对象,以便将其键用作属性名,可以使用以下代码行之一:
[PSCustomObject]@{a=1;b=2;c=3}
# OR
New-Object PSObject -Property @{a=1;b=2;c=3}
# NOTE: Both have the type PSCustomObject
如果要将多个哈希表
转换为其键为属性名的对象,可以使用以下代码:
$numberofobjects = 1000
$objects = (0..$numberofobjects) |% {
New-Object psobject -Property @{'Name'="object$_";'Path'="Path$_"}
}
$lookupobjects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Path'="Path$_";'Share'="Share$_"}
}
$method1 = {
foreach ($object in $objects) {
$object | Add-Member NoteProperty -Name Share -Value ($lookupobjects | ?{$_.Path -eq $object.Path} | select -First 1 -ExpandProperty share)
}
}
Measure-Command $method1 | select totalseconds
$objects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Name'="object$_";'Path'="Path$_"}
}
$lookupobjects = (0..$numberofobjects) | % {
New-Object psobject -Property @{'Path'="Path$_";'Share'="Share$_"}
}
$method2 = {
$hash = @{}
foreach ($obj in $lookupobjects) {
$hash.($obj.Path) = $obj.share
}
foreach ($object in $objects) {
$object |Add-Member NoteProperty -Name Share -Value ($hash.($object.path)).share
}
}
Measure-Command $method2 | select totalseconds
@{name='a';num=1},@{name='b';num=2} |
% { [PSCustomObject]$_ }
# OR
@{name='a';num=1},@{name='b';num=2} |
% { New-Object PSObject -Property $_ }
<#
Outputs:
name num
---- ---
a 1
b 2
#>
@{name='a';num=1},@{name='b';num=2}|
%{[PSCustomObject]$\
#或
@{name='a';num=1},@{name='b';num=2}|
%{新对象PSObject-属性$}
很难找到有关NoteProperty
的文档,除了NoteProperty
之外,没有任何-MemberType对添加对象属性有意义。Windows PowerShell Cookbook(第三版)将Noteproperty
Membertype定义为:
由您提供的初始值定义的特性
- Lee,H.(2013)。Windows PowerShell食谱。奥莱利传媒有限公司。895
我们的Windows PKI中有一堆模板,我们需要一个脚本,它必须与所有活动模板一起工作。我们不需要它