mas*_*asi 30 powershell powershell-3.0 psobject
任何人都能解释一下细节吗?如果我使用创建对象
$var = [PSObject]@{a=1;b=2;c=3}
Run Code Online (Sandbox Code Playgroud)
然后我使用getType()PowerShell 查找它的类型告诉我它的类型为Hashtable.
当使用Get-Member(别名gm)来检查对象时,很明显已经创建了一个哈希表,因为它有一个keys和一个values属性.那么"普通"散列表的区别是什么?
另外,使用PSCustomObject有什么好处?使用这样的东西创建一个
$var = [PSCustomObject]@{a=1;b=2;c=3}
Run Code Online (Sandbox Code Playgroud)
对我来说唯一可见的区别是PSCustomObject的不同数据类型.此外,还有一个检查gm显示现在每个键都已添加为NoteProperty对象,而不是键和值属性.
但我有什么优势?我可以通过使用其键来访问我的值,就像在哈希表中一样.我可以在PSCustomObject中存储多个简单的键值对(例如键对象对),就像在哈希表中一样.那有什么好处?有什么重要的区别吗?
tko*_*sih 31
使用一种情况[PSCustomObject]而不是HashTable在需要它们的集合时.以下是说明它们处理方式的不同之处:
$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
Run Code Online (Sandbox Code Playgroud)
Format-Table将产生以下结果$Hash:
Name Value
---- -----
Name Object 1
Squared 1
Index 1
Name Object 2
Squared 4
Index 2
Name Object 3
Squared 9
...
Run Code Online (Sandbox Code Playgroud)
以下是$CustomObject:
Name Index Squared
---- ----- -------
Object 1 1 1
Object 2 2 4
Object 3 3 9
Object 4 4 16
Object 5 5 25
...
Run Code Online (Sandbox Code Playgroud)
同样的事情发生了Export-Csv,因此使用的原因[PSCustomObject]而不仅仅是普通的HashTable.
小智 17
说我想创建一个文件夹.如果我使用PSObject,你可以通过查看它来判断它是错误的
PS > [PSObject] @{Path='foo'; Type='directory'}
Name Value
---- -----
Path foo
Type directory
Run Code Online (Sandbox Code Playgroud)
但是PSCustomObject看起来是正确的
PS > [PSCustomObject] @{Path='foo'; Type='directory'}
Path Type
---- ----
foo directory
Run Code Online (Sandbox Code Playgroud)
然后我可以管道对象
[PSCustomObject] @{Path='foo'; Type='directory'} | New-Item
Run Code Online (Sandbox Code Playgroud)
Loï*_*HEL 12
我认为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()
Run Code Online (Sandbox Code Playgroud)
您可以使用它来控制PSObject属性的排序顺序(请参阅PSObject排序)
Dav*_*e F 10
包装对象,以提供可用成员的替代视图以及扩展它们的方式。成员可以是方法,属性,参数化属性等。
换句话说,a PSObject是一个对象,您可以在创建对象后向其中添加方法和属性。
哈希表(也称为字典或关联数组)是一种紧凑的数据结构,用于存储一个或多个键/值对。
...
哈希表经常被使用,因为它们对于查找和检索数据非常有效。
您可以使用a之PSObject类的,Hashtable因为PowerShell允许您向中添加属性PSObjects,但是您不应这样做,因为您将失去Hashtable对Keysand 功能等特定功能的访问权限Values。同样,可能会有性能成本和额外的内存使用情况。
PowerShell文档包含以下有关的信息PSCustomObject:
当使用不带参数的PSObject的构造函数时,用作占位符BaseObject。
这是我不清楚,但在PowerShell的论坛一个帖子从一些PowerShell的书的合着者似乎更加明显:
[PSCustomObject]是类型加速器。它构造了一个PSObject,但这样做的方式导致哈希表键成为属性。PSCustomObject本身不是对象类型,而是一个过程快捷方式。... PSCustomObject是一个占位符,当不使用构造函数参数调用PSObject时将使用该占位符。
关于您的代码,@{a=1;b=2;c=3}是Hashtable。[PSObject]@{a=1;b=2;c=3}不会将转换Hashtable为PSObject或产生错误。该对象仍然是Hashtable。但是,[PSCustomObject]@{a=1;b=2;c=3}将Hashtable转换为PSObject。我找不到说明为什么会发生这种情况的文档。
如果要将a Hashtable转换为对象以将其键用作属性名称,则可以使用以下代码行之一:
[PSCustomObject]@{a=1;b=2;c=3}
# OR
New-Object PSObject -Property @{a=1;b=2;c=3}
# NOTE: Both have the type PSCustomObject
Run Code Online (Sandbox Code Playgroud)
如果要将大量的Hashtables键转换为键为属性名称的对象,可以使用以下代码:
@{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
#>
Run Code Online (Sandbox Code Playgroud)
查找有关的文档NoteProperty非常困难。在Add-Member文档中,除了-MemberType添加对象属性外没有其他有意义的东西NoteProperty。在Windows PowerShell中食谱(第3版)中定义的NotepropertyMembertype为:
由您提供的初始值定义的属性
- Lee,H.(2013年)。Windows PowerShell食谱。O'Reilly Media,Inc. 895。
我认为你会看到的最大区别是性能。看看这篇博文:
作者运行了以下代码:
$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
Run Code Online (Sandbox Code Playgroud)
博客作者的输出:
TotalSeconds
------------
167.8825285
0.7459279
Run Code Online (Sandbox Code Playgroud)
他对代码结果的评论是:
当你把它们放在一起时,你可以看到速度的差异。对象方法在我的计算机上需要 167 秒,而哈希表方法将需要不到一秒的时间来构建哈希表,然后进行查找。
以下是其他一些更微妙的好处: PowerShell 3.0 中的自定义对象默认显示
| 归档时间: |
|
| 查看次数: |
36937 次 |
| 最近记录: |