誰でも詳細を説明できますか?を使用してオブジェクトを作成する場合
_$var = [PSObject]@{a=1;b=2;c=3}
_
そして、getType()
を使用してそのタイプを探しますPowerShellは、タイプHashtableであることを教えてくれます。
Get-Member (別名gm
)を使用してオブジェクトを検査する場合、keys
とvalues
プロパティ。それでは、「通常の」ハッシュテーブルとの違いは何ですか?
また、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
<#
Blog author's output:
TotalSeconds
------------
167.8825285
0.7459279
#>
コード結果に関する彼のコメントは次のとおりです。
速度をすべて合わせると、速度の違いがわかります。私のコンピューターではオブジェクトメソッドは167秒かかりますが、ハッシュテーブルメソッドはハッシュテーブルを作成してからルックアップを行うのに1秒もかかりません。
次に、他のより微妙な利点の一部を示します。PowerShell 3.0でのカスタムオブジェクトのデフォルト表示
HashTable
の代わりに[PSCustomObject]
が使用される1つのシナリオは、それらのコレクションが必要な場合です。次に、それらの処理方法の違いを示します。
$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
Format-Table
は、$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
...
Export-Csv
でも同じことが起こります。したがって、単なるHashTable
の代わりに[PSCustomObject]
を使用する理由です。
フォルダーを作成するとします。 PSObjectを使用している場合、それを見て間違っていることがわかります。
PS > [PSObject] @{Path='foo'; Type='directory'}
Name Value
---- -----
Path foo
Type directory
ただし、PSCustomObjectは正しいように見えます
PS > [PSCustomObject] @{Path='foo'; Type='directory'}
Path Type
---- ----
foo directory
オブジェクトをパイプできます
[PSCustomObject] @{Path='foo'; Type='directory'} | New-Item
PSObjectの利点の1つは、それを使用してカスタムメソッドを作成できることです。
例えば、
$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プロパティの並べ替え順序を制御できます(PSObject並べ替えを参照)
オブジェクトをラップして、使用可能なメンバーの代替ビューとそれらを拡張する方法を提供します。メンバーは、メソッド、プロパティ、パラメータ化されたプロパティなどです。
つまり、PSObject
は、作成後にメソッドとプロパティを追加できるオブジェクトです。
ハッシュテーブルは、辞書または連想配列とも呼ばれ、1つ以上のキー/値のペアを格納するコンパクトなデータ構造です。
...
ハッシュテーブルは、データの検索と取得に非常に効率的であるため、頻繁に使用されます。
PowerShellではPSObject
にプロパティを追加できるため、Hashtable
のようにPSObjects
を使用できますが、Hashtable
やKeys
プロパティなど、Values
固有の機能へのアクセスを失うため、これを行うべきではありません。また、パフォーマンスコストと追加のメモリ使用量がある場合があります。
PowerShellドキュメントには、PSCustomObject
に関する以下の情報があります :
パラメーターのないPSObjectのコンストラクターが使用される場合、プレースホルダーBaseObjectとして機能します。
これは私には不明瞭でしたが、 PowerShellフォーラムへの投稿 from 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
に変換します。これが起こる理由を説明したドキュメントを見つけることができませんでした。
プロパティ名としてキーを使用するために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
多数の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
#>
NoteProperty
に関するドキュメントを見つけることは困難でした。 Add-Member
ドキュメント では、NoteProperty
以外のオブジェクトプロパティを追加するのに意味のある-MemberType
はありません。 Windows PowerShell Cookbook(第3版)では、Noteproperty
Membertypeを次のように定義しました。
指定した初期値で定義されたプロパティ
- リー、H。(2013)。 Windows PowerShell Cookbook。 O'Reilly Media、Inc. p。 895。