次の方法で共有


about_Member-Access_Enumeration

簡単な説明

メンバー アクセス演算子を使用する場合のリスト コレクション項目の自動列挙について説明します。

詳細な説明

PowerShell 3.0 以降、 member-access 列挙型 機能により、リスト コレクション オブジェクトでメンバー アクセス演算子 (.) を使用する利便性が向上しました。 メンバー アクセス演算子を使用してコレクションに存在しないメンバーにアクセスすると、PowerShell はコレクション内の項目を自動的に列挙し、各アイテムの指定されたメンバーにアクセスしようとします。

メンバー アクセス列挙は、よりシンプルで短いコードを記述するのに役立ちます。 コレクション オブジェクトをパイプ処理して ForEach-Object したり、 ForEach()intrinsic メソッドを使用したり コレクション内の各項目のメンバーにアクセスしたりする代わりに、コレクション オブジェクトのメンバー アクセス演算子を使用できます。

これらのコマンドは、メンバー アクセス演算子の使用を示す最後のコマンドと機能的に同じです。

Get-Service -Name event* | ForEach-Object -Process { $_.DisplayName }
(Get-Service -Name event*).ForEach({ $_.DisplayName })
(Get-Service -Name event*).DisplayName
Windows Event Log
COM+ Event System

Windows Event Log
COM+ Event System

Windows Event Log
COM+ Event System

Note

メンバー アクセス演算子を使用すると、コレクション内の項目のプロパティの値を取得できますが、それを使用して直接設定することはできません。 詳細については、 about_Arraysを参照してください。

任意のオブジェクトでメンバー アクセス演算子を使用し、指定したメンバーがそのオブジェクトに存在する場合、メンバーが呼び出されます。 プロパティ メンバーの場合、演算子はそのプロパティの値を返します。 メソッド メンバーの場合、演算子はオブジェクトでそのメソッドを呼び出します。

指定したメンバーを持たないリスト コレクション オブジェクトでメンバー アクセス演算子を使用すると、PowerShell によってそのコレクション内の項目が自動的に列挙され、列挙された各アイテムに対してメンバー アクセス演算子が使用されます。

オブジェクトがリスト コレクションであるかどうかを確認するには、その型が IList インターフェイスを実装しているかどうかを確認します。

$List = @('a', 'b')
$Hash = @{ a = 'b' }
$List.GetType().ImplementedInterfaces.Name -contains 'IList'
$Hash.GetType().ImplementedInterfaces.Name -contains 'IList'
True

False

プロパティのメンバー アクセス列挙中に、演算子は、そのプロパティを持つ各項目のプロパティの値を返します。 指定したプロパティを持つ項目がない場合、演算子は $nullを返します。

メソッドのメンバー アクセス列挙中に、演算子はコレクション内の各項目に対してメソッドの呼び出しを試みます。 コレクション内の項目に指定されたメソッドがない場合、演算子は MethodNotFound 例外を返します。

警告

メソッドのメンバー アクセス列挙では、コレクション内の各項目に対してメソッドが呼び出されます。 呼び出すメソッドが変更を行うと、コレクション内のすべての項目に対して変更が行われます。 列挙中にエラーが発生した場合、メソッドは、エラーの前に列挙された項目でのみ呼び出されます。 安全性を高める場合は、項目を手動で列挙し、エラーを明示的に処理することを検討してください。

次の例では、考えられるすべてのシナリオでのメンバー アクセス演算子の動作について詳しく説明します。

リスト以外のオブジェクトのメンバーへのアクセス

リスト コレクションではなく、メンバーを持つオブジェクトに対してメンバー アクセス演算子を使用すると、コマンドはそのオブジェクトのメソッドのプロパティまたは出力の値を返します。

$MyString = 'abc'
$MyString.Length
$MyString.ToUpper()
3

ABC

メンバーを持たないリスト以外のオブジェクトでメンバー アクセス演算子を使用すると、プロパティを指定した場合は $null が返され、メソッドを指定した場合は MethodNotFound エラーが返されます。

$MyString = 'abc'
$null -eq $MyString.DoesNotExist
$MyString.DoesNotExist()
True

InvalidOperation:
Line |
   3 |  $MyString.DoesNotExist()
     |  ~~~~~~~~~~~~~~~~~~~~~~~~
     | Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.

リスト コレクション オブジェクトのメンバーへのアクセス

メンバーを持つコレクション オブジェクトでメンバー アクセス演算子を使用すると、コレクション オブジェクトのプロパティ値またはメソッドの結果が常に返されます。

コレクションに存在するが、その項目には存在しないメンバーへのアクセス

この例では、指定したメンバーはコレクションに存在しますが、コレクション内の項目には存在しません。

[System.Collections.Generic.List[string]]$Collection = @('a', 'b')
$Collection.IsReadOnly
$Collection.Add('c')
$Collection
False

a
b
c

コレクションとその項目に存在するメンバーへのアクセス

この例では、指定したメンバーはコレクションとその中の項目の両方に存在します。 コレクションのメンバー アクセス演算子を使用したコマンドの結果と、 ForEach-Objectのコレクション項目でメンバー アクセス演算子を使用した結果を比較します。 コレクションでは、演算子はコレクション オブジェクトのプロパティ値またはメソッドの結果を返し、その中の項目は返しません。

[System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
$Collection.Count
$Collection | ForEach-Object -Process { $_.Count }
$Collection.ToString()
$Collection | ForEach-Object -Process { $_.ToString() }
3

1
1
1

System.Collections.Generic.List`1[System.String]

a
b
c

Note

System.Collections.IDictionary インターフェイスを実装するコレクション (HashTableOrderedDictionary など) の動作は異なります。 プロパティと同じ名前のキーを持つディクショナリでメンバー アクセス演算子を使用すると、プロパティの代わりにキーの値が返されます。

ディクショナリ オブジェクトのプロパティ値には、 psbaseintrinsic メンバーを使用してアクセスできます。 たとえば、キー名が keys で、 HashTable キーのコレクションを返す場合は、次の構文を使用します。

$hashtable.PSBase.Keys

コレクション内のすべての項目に存在するが、それ自体には存在しないメンバーへのアクセス

メンバーを持たないコレクション オブジェクトに対してメンバー アクセス演算子を使用する場合、PowerShell はコレクション内の項目を列挙し、各アイテムのプロパティ値またはメソッドの結果を返します。

[System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
$Collection.Length
$Collection.ToUpper()
1
1
1

A
B
C

コレクションとその項目のどちらにも存在しないメンバーにアクセスする

メンバーを持たないコレクション オブジェクトに対してメンバー アクセス演算子を使用し、その中の項目も実行しない場合、プロパティを指定した場合はコマンドから $null が返され、メソッドを指定した場合は MethodNotFound エラーが返されます。

[System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
$null -eq $Collection.DoesNotExist
$Collection.DoesNotExist()
True

InvalidOperation:
Line |
   3 |  $Collection.DoesNotExist()
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.

コレクション オブジェクトにはメンバーがないため、PowerShell はコレクション内の項目を列挙しました。 MethodNotFound エラーは、System.StringSystem.Collections.Generic.List の代わりにメソッドが含まれていないことを示しています。

コレクション内の一部の項目にのみ存在するメソッドへのアクセス

メンバー アクセス演算子を使用して、メソッドを持たないコレクション オブジェクトのメソッドにアクセスし、コレクション内の一部の項目にのみメソッドを持つ場合、このコマンドは、メソッドを持たないコレクション内の最初の項目に対して MethodNotFound エラーを返します。 一部の項目でメソッドが呼び出されても、コマンドはエラーのみを返します。

@('a', 1, 'c').ToUpper()
InvalidOperation: Method invocation failed because [System.Int32] does not contain a method named 'ToUpper'.

コレクション内の一部の項目にのみ存在するプロパティへのアクセス

メンバー アクセス演算子を使用して、プロパティを持たないコレクション オブジェクトのプロパティにアクセスし、コレクション内の一部の項目にのみプロパティを持つ場合、このコマンドは、プロパティを持つコレクション内の各項目のプロパティ値を返します。

$CapitalizedProperty = @{
    MemberType = 'ScriptProperty'
    Name       = 'Capitalized'
    Value      = { $this.ToUpper() }
    PassThru   = $true
}
[System.Collections.Generic.List[object]]$MixedCollection = @(
    'a'
    ('b' | Add-Member @CapitalizedProperty)
    ('c' | Add-Member @CapitalizedProperty)
    'd'
)
$MixedCollection.Capitalized
B
C

参照