about_Member-Access_Enumeration

簡短描述

描述使用成員存取運算符時清單集合項目的自動列舉。

詳細描述

從 PowerShell 3.0 開始, 成員存取列舉 功能可改善在清單集合物件上使用成員存取運算子 (.) 的便利性。 當您使用成員存取運算符來存取集合中不存在的成員時,PowerShell 會自動列舉集合中的專案,並嘗試存取每個專案上的指定成員。

成員存取列舉可協助您撰寫更簡單且較短的程序代碼。 您可以對集合物件 ForEach-Object 使用成員存取運算元,而不是使用 ForEach()內部方法 ,存取集合中每個專案上的成員。

這些命令在功能上與最後一個示範使用成員存取運算子的命令相同:

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

注意

您可以使用成員存取運算符來取得集合中專案上的屬性值,但您無法使用它直接設定它們。 如需詳細資訊,請參閱 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

當您在沒有成員的非清單物件上使用成員存取運算符時,如果您指定屬性或 MethodNotFound 錯誤,如果您指定方法,命令會傳回 $null

$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

注意

實作 System.Collections.IDictionary 介面的集合,例如 HashTableOrderedDictionary,有不同的行為。 當您在具有與屬性相同名稱的字典上使用成員存取運算符時,它會傳回索引鍵的值,而不是屬性的值。

您可以使用 psbase 內部成員來存取字典物件的屬性值 例如,如果索引鍵名稱是 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

存取集合及其專案上不存在的成員

當您在集合物件上使用成員存取運算子時,該物件沒有成員,而且其中都沒有專案,如果您指定屬性或指定方法,MethodNotFound命令會$null傳回 。

[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.String 不包含 方法,而不是 System.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

另請參閱