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 $null
de 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.