Delen via


about_Member-Access_Enumeration

Korte beschrijving

Beschrijft de automatische inventarisatie van verzamelingen bij het gebruik van de lidtoegangsoperator.

Lange beschrijving

PowerShell onderhoudt een lijst met typen die kunnen worden opgesomd. Vanaf PowerShell 3.0 verbetert de opsomming voor ledentoegang het gemak van het gebruik van de operator voor lidtoegang (.) op verzamelingsobjecten die kunnen worden opgesomd.

Met opsomming voor lidtoegang kunt u eenvoudigere en kortere code schrijven. In plaats van een verzamelingsobject door te geven aan ForEach-Object of de ForEach()intrinsieke methode te gebruiken voor toegang tot leden voor elk item in de verzameling, kunt u de operator voor lidtoegang gebruiken op het verzamelingsobject.

De volgende voorbeelden produceren dezelfde resultaten. In het laatste voorbeeld ziet u het gebruik van de operator voor lidtoegang:

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

Notitie

U kunt de operator voor lidtoegang gebruiken om de waarden van een eigenschap op te halen voor items in een verzameling, maar u kunt deze niet gebruiken om ze rechtstreeks in te stellen. Zie about_Arrays voor meer informatie. Lidtoegang-enumeratie is een handige functie. Er kunnen subtiele gedrags- en prestatieverschillen zijn tussen de verschillende opsommingsmethoden.

Wanneer u de operator voor lidtoegang op een object gebruikt en het opgegeven lid op dat object bestaat, wordt het lid aangeroepen. Wanneer u de operator voor lidtoegang gebruikt voor een verzamelingsobject dat niet het opgegeven lid bevat, somt PowerShell de items in die verzameling op en gebruikt vervolgens de operator voor lidtoegang voor elk opgesomd item.

Tijdens de inventarisatie van lidtoegang voor een eigenschap retourneert de operator de waarde van de eigenschap voor elk item met die eigenschap. Als er geen items de opgegeven eigenschap hebben, retourneert $nullde operator .

Tijdens de inventarisatie van lidtoegang voor een methode probeert de operator de methode aan te roepen voor elk item in de verzameling. Als een item in de verzameling niet over de opgegeven methode beschikt, retourneert de operator de MethodNotFound-uitzondering.

Waarschuwing

Tijdens de inventarisatie van lidtoegang voor een methode wordt de methode aangeroepen voor elk item in de verzameling. Als de methode die u aanroept wijzigingen aanbrengt, worden de wijzigingen aangebracht voor elk item in de verzameling. Als er een fout optreedt tijdens de inventarisatie, wordt de methode alleen aangeroepen voor de items die vóór de fout zijn geïnventariseerd. Voor extra veiligheid kunt u de items handmatig inventariseren en expliciet eventuele fouten afhandelen.

Toegang tot leden van een niet-itereerbaar object

Wanneer u de lidtoegangsoperator gebruikt voor een object dat geen opsombare verzameling is, roept PowerShell het lid aan om de waarde van de eigenschap of de uitvoer van de methode voor dat object terug te geven.

PS> $MyString = 'abc'
PS> $MyString.Length
3
PS> $MyString.ToUpper()
ABC

Wanneer u de operator voor lidtoegang gebruikt voor een niet-enumereerbaar object dat niet over het lid beschikt, retourneert PowerShell $null voor de ontbrekende eigenschap of een MethodNotFound--fout voor de ontbrekende methode.

PS> $MyString = 'abc'
PS> $null -eq $MyString.DoesNotExist
True
PS> $MyString.DoesNotExist()
InvalidOperation: Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.

Leden van een verzameling benaderen

Wanneer u de operator voor lidtoegang gebruikt voor een verzamelingsobject dat het lid heeft, wordt altijd de eigenschapswaarde of het methoderesultaat voor het verzamelingsobject geretourneerd.

Toegang tot elementen die bestaan in de verzameling, maar niet in de items

In dit voorbeeld bestaan de opgegeven leden in de verzameling, maar niet de items erin.

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

Toegang tot leden die bestaan in de verzameling en de bijbehorende items

In dit voorbeeld bestaan de opgegeven leden in zowel de verzameling als de items erin. Vergelijk de resultaten van de opdrachten met behulp van de operator voor lidtoegang in de verzameling met de resultaten van het gebruik van de operator voor lidtoegang op de verzamelingsitems in ForEach-Object. In de verzameling retourneert de operator de eigenschapswaarde of het methoderesultaat voor het verzamelingsobject en niet de items erin.

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

Notitie

Verzamelingen die de Interface System.Collections.IDictionary implementeren, zoals HashTable en OrderedDictionary, hebben een ander gedrag. Wanneer u de operator voor lidtoegang gebruikt in een woordenlijst met een sleutel met dezelfde naam als een eigenschap, wordt de waarde van de sleutel geretourneerd in plaats van de eigenschap.

U kunt de eigenschapswaarde van het woordenboekobject openen met het intrinsiek lid van psbase. Als de sleutelnaam bijvoorbeeld is keys en u de verzameling van de HashTable-sleutels wilt retourneren, gebruikt u deze syntaxis:

$hashtable.psbase.Keys

Toegang tot leden die niet op zichzelf bestaan, maar aanwezig zijn op alle items in een verzameling.

Wanneer u de lidtoegangsoperator gebruikt op een verzamelingsobject dat zelf het lid niet heeft, maar de items daarin wel, voert PowerShell een enumeratie van de items in de verzameling uit en retourneert de eigenschapswaarde of het resultaat van de methode voor elk item.

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

Toegang krijgen tot leden die niet bestaan op de verzameling of de items ervan

Wanneer u de lidtoegangsoperator gebruikt voor een verzamelingsobject dat het lid niet heeft en ook geen van de items, retourneert de opdracht $null als u een eigenschap opgeeft of een MethodNotFound fout als u een methode specificeert.

PS> [System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
PS> $null -eq $Collection.DoesNotExist
True
PS> $Collection.DoesNotExist()
InvalidOperation: Method invocation failed because [System.String] does not
contain a method named 'DoesNotExist'.

Omdat het verzamelingsobject niet over het lid beschikt, heeft PowerShell de items in de verzameling geïnventariseerd. U ziet dat de MethodNotFound--fout aangeeft dat System.String de methode niet bevat in plaats van System.Collections.Generic.List.

Toegangsmethoden die alleen bestaan op sommige items in een verzameling

Wanneer u de operator voor lidtoegang gebruikt om toegang te krijgen tot een methode op een verzamelingsobject dat niet over de methode beschikt en slechts sommige items in de verzameling deze methode hebben, retourneert de instructie een MethodNotFound fout voor het eerste item in de verzameling dat niet over de methode beschikt. Hoewel de methode op sommige items wordt aangeroepen, retourneert de opdracht alleen de fout.

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

Toegangseigenschappen die alleen bestaan op sommige items in een verzameling

Wanneer u de lidtoegangsoperator gebruikt om toegang te krijgen tot een eigenschap op een verzamelingsobject, en dit object niet over die eigenschap beschikt maar slechts enkele items in de verzameling dat wel hebben, retourneert de opdracht voor elk item in de verzameling dat de eigenschap heeft, de waarde van die eigenschap.

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

Toegang tot leden van een geneste collectie

Wanneer een doorloopbare collectie een geneste collectie bevat, wordt lidtoegangsopsomming toegepast op elke geneste collectie.

$a is bijvoorbeeld een matrix die twee elementen bevat: een geneste matrix met tekenreeksen en één tekenreeks.

# Get the count of items in the array.
PS> $a.Count
2
# Get the count of items in each nested item.
PS> $a.GetEnumerator().Count
2
1
# Call the ToUpper() method on all items in the nested array.
PS> $a = @(, ('bar', 'baz'), 'foo')
PS> $a.ToUpper()
BAR
BAZ
FOO

Wanneer u de lidmaatschapstoegang-operator gebruikt, enumereert PowerShell de items in $a en roept vervolgens de methode ToUpper() aan voor alle items.

Notities

Zoals eerder vermeld, kunnen er subtiele gedrags- en prestatieverschillen zijn tussen de verschillende opsommingsmethoden.

Fouten resulteren in verloren uitvoer

Wanneer de opsomming van lidtoegangsrechten wordt beëindigd door een fout, wordt de uitvoer van eerdere succesvolle methodeaanroepen niet geretourneerd. Terminale foutvoorwaarden zijn onder andere:

  • het geënumereerde object mist de aangeroepen methode
  • de aangeroepen methode veroorzaakt een fatale fout

Bekijk het volgende voorbeeld:

class Class1 { [Object] Foo() { return 'Bar' } }
class Class2 { [void] Foo() { throw 'Error' } }
class Class3 {}

$example1 = ([Class1]::new(), [Class1]::new())
$example2 = ([Class1]::new(), [Class2]::new())
$example3 = ([Class1]::new(), [Class3]::new())

Beide items in $example1 hebben de methode Foo(), waardoor de methode-aanroep slaagt.

PS> $example1.Foo()
Bar
Bar

De methode Foo() op het tweede item in $example2 genereert een fout, waardoor de opsomming mislukt.

PS> $example2.Foo()
Exception:
Line |
   2 |  class Class2 { [void] Foo() { throw 'Error' } }
     |                                ~~~~~~~~~~~~~
     | Error

Het tweede item in $example2 heeft niet de methode Foo(), waardoor de opsomming mislukt.

PS> $example3.Foo()
InvalidOperation: Method invocation failed because [Class3] does not contain
a method named 'Foo'.

Vergelijk dit met opsomming met behulp van ForEach-Object

PS> $example2 | ForEach-Object -MemberName Foo
Bar
ForEach-Object: Exception calling "Foo" with "0" argument(s): "Error"
PS> $example3 | ForEach-Object -MemberName Foo
Bar

U ziet dat in de uitvoer de geslaagde aanroep voor Foo() op het eerste item in de matrix wordt weergegeven.

Verzamelingen met PSCustomObject-exemplaren

Als de verzameling objecten exemplaren van PSCustomObject items bevat, retourneert PowerShell onverwacht $null waarden wanneer de geopende eigenschap ontbreekt.

In de volgende voorbeelden heeft ten minste één object de eigenschap waarnaar wordt verwezen.

PS> $foo = [pscustomobject]@{ Foo = 'Foo' }
PS> $bar = [pscustomobject]@{ Bar = 'Bar' }
PS> $baz = [pscustomobject]@{ Baz = 'Baz' }
PS> ConvertTo-Json ($foo, $bar, $baz).Foo
[
  "Foo",
  null,
  null
]
PS> ConvertTo-Json ((Get-Process -Id $PID), $foo).Name
[
  "pwsh",
  null
]

U zou verwachten dat PowerShell één object retourneert voor het item waarvoor de eigenschap is opgegeven. In plaats daarvan retourneert PowerShell ook een $null waarde voor elk item dat niet over de eigenschap beschikt.

Zie PowerShell-probleem #13752voor meer informatie over dit gedrag.

Zie ook