51

誰かが詳細を説明できますか?を使用してオブジェクトを作成する場合

$var = [PSObject]@{a=1;b=2;c=3}

getType()次に、 PowerShellを使用してそのタイプを検索すると、Hashtableタイプであることがわかります。

Get-Member(エイリアス)を使用してオブジェクトを検査する場合、ハッシュテーブルにはとプロパティgmがあるため、ハッシュテーブルが作成されていることは明らかです。では、「通常の」ハッシュテーブルとの違いは何ですか?keysvalues

また、PSCustomObjectを使用する利点は何ですか?このようなものを使用して作成する場合

$var = [PSCustomObject]@{a=1;b=2;c=3}

私にとって目に見える唯一の違いは、PSCustomObjectのデータ型が異なることです。また、キーと値のプロパティの代わりに、を使用して検査すると、gmすべてのキーがNotePropertyオブジェクトとして追加されていることがわかります。

しかし、私にはどのような利点がありますか?ハッシュテーブルと同じように、キーを使用して値にアクセスできます。PSCustomObjectには、ハッシュテーブルと同じように、単純なキーと値のペア(たとえば、キーとオブジェクトのペア)以上のものを格納できます。では、利点は何ですか?重要な違いはありますか?

4

6 に答える 6

46

[PSCustomObject]の代わりにが使用されるシナリオの1つ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

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使用する理由です。[PSCustomObject]HashTable

于 2014-05-09T03:10:10.570 に答える
35

フォルダを作成したいとします。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
于 2014-11-11T17:56:34.097 に答える
31

PSObjectドキュメントから

使用可能なメンバーの代替ビューとそれらを拡張する方法を提供するオブジェクトをラップします。メンバーには、メソッド、プロパティ、パラメータ化されたプロパティなどがあります。

つまり、aPSObjectは、作成後にメソッドとプロパティを追加できるオブジェクトです。

「ハッシュテーブルについて」のドキュメントから

ハッシュテーブルは、辞書または連想配列とも呼ばれ、1つ以上のキーと値のペアを格納するコンパクトなデータ構造です。

..。

ハッシュテーブルは、データの検索と取得に非常に効率的であるため、頻繁に使用されます。

PowerShellではにプロパティを追加できるため、のPSObjectようなものを使用できますが、プロパティなどの特定の機能にアクセスできなくなるため、これを行うべきではありません。また、パフォーマンスコストと追加のメモリ使用量が発生する可能性があります。HashtablePSObjectsHashtableKeysValues

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}しません。オブジェクトは。のままです。ただし、をに変換します。なぜこれが起こるのかを説明するドキュメントを見つけることができませんでした。HashtablePSObjectHashtable[PSCustomObject]@{a=1;b=2;c=3}HashtablePSObject

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-MemberType以外のオブジェクトプロパティを追加するのに意味のあるものはありませんNotePropertyWindows PowerShellクックブック(第3版)では、メンバータイプを次のように定義してNotepropertyいます。

指定した初期値によって定義されるプロパティ

  • Lee、H.(2013)。WindowsPowerShellクックブック。O'Reilly Media、Inc.p。895。
于 2018-05-06T05:52:12.943 に答える
14

PSObjectの利点の1つは、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プロパティの並べ替え順序を制御できます(PSObjectの並べ替えを参照) 。

于 2013-09-16T19:14:58.980 に答える
7

あなたが見る最大の違いはパフォーマンスだと思います。このブログ投稿をご覧ください:

オブジェクトを効率的に組み合わせる–ハッシュテーブルを使用してオブジェクトのコレクションにインデックスを付けます

作成者は次のコードを実行しました。

$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

ブログ作成者の出力:

TotalSeconds
------------
 167.8825285
   0.7459279

コード結果に関する彼のコメントは次のとおりです。

まとめると速度の違いがわかります。オブジェクトメソッドは私のコンピューターでは167秒かかりますが、ハッシュテーブルメソッドはハッシュテーブルを作成してからルックアップを実行するのに1秒もかかりません。

その他のより微妙な利点のいくつかを次に示し ます。PowerShell3.0でのカスタムオブジェクトのデフォルト表示

于 2012-12-23T18:07:38.567 に答える
0

Windows-PKIには多数のテンプレートがあり、すべてのアクティブなテンプレートで機能する必要があるスクリプトが必要でした。テンプレートを動的に追加したり削除したりする必要はありません。私にとって完璧に機能するのは(読むのもとても「自然」なので)、次のとおりです。

$templates = @(
    [PSCustomObject]@{Name = 'template1'; Oid = '1.1.1.1.1'}
    [PSCustomObject]@{Name = 'template2'; Oid = '2.2.2.2.2'}
    [PSCustomObject]@{Name = 'template3'; Oid = '3.3.3.3.3'}
    [PSCustomObject]@{Name = 'template4'; Oid = '4.4.4.4.4'}
    [PSCustomObject]@{Name = 'template5'; Oid = '5.5.5.5.5'}
)

foreach ($template in $templates)
{
   Write-Output $template.Name $template.Oid
}
于 2021-03-13T02:28:47.910 に答える