about_Member-Access_Enumeration
Korte beschrijving
Beschrijft de automatische inventarisatie van verzamelingen wanneer u de operator voor lidtoegang gebruikt.
Lange beschrijving
PowerShell onderhoudt een lijst met typen die kunnen worden opgesomd. Vanaf PowerShell 3.0 maakt de functie voor ledentoegang het gebruik van de lidtoegang-operator (.
) gemakkelijker bij verzamelingsobjecten die op te sommen zijn.
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 wordt het gebruik van de lidtoegangsoperator gedemonstreerd.
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. De opsomming van lidmaatschaps-toegang is een handige functie. Er kunnen subtiele gedrags- en prestatieverschillen zijn tussen de verschillende opsommingsmethoden.
Wanneer je de operator voor leden toegang op een object gebruikt en het gespecificeerde lid op dat object bestaat, wordt het lid aangeroepen. Wanneer u de operator voor lidtoegang gebruikt voor een verzamelingsobject dat niet het opgegeven lid heeft, doorloopt PowerShell de items in die verzameling en gebruikt de operator voor lidtoegang op elk afzonderlijk genummerd 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 krijgen tot leden van een niet-opvraagbaar object
Wanneer u de lidtoegangsoperator gebruikt voor een object dat geen enumerable 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()
Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.
At line:1 char:1
+ $MyString.DoesNotExist()
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Toegang krijgen tot leden van een verzamelingsobject
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 leden die bestaan in de verzameling, maar niet de bijbehorende 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 op alle items in een verzameling bestaan, maar niet op zichzelf
Wanneer u de operator voor lidtoegang gebruikt op een verzamelingsobject dat het lid niet heeft maar waarvan de items dat wel hebben, enumereert PowerShell de items in de verzameling 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 in de collectie of zijn items
Wanneer u de lidtoegang-operator gebruikt voor een verzamelingsobject dat het lid niet bevat en ook de items dat niet doen, retourneert de opdracht $null
als u een specifieke eigenschap opgeeft of een MethodNotFound
-fout als u een specifieke methode opgeeft.
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 voor een verzamelingsobject dat niet over de methode beschikt en slechts enkele items in de verzameling deze hebben, retourneert de opdracht een MethodNotFound
fout voor het eerste item in de verzameling die 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 van een verzamelingsobject dat deze eigenschap niet heeft en alleen sommige items in de verzameling deze eigenschap wel hebben, retourneert het commando de eigenschapswaarde voor elk item in de verzameling die de eigenschap heeft.
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 krijgen tot leden van een geneste verzameling
Wanneer een telbare verzameling een ingebedde collectie bevat, wordt toegang tot leden toegepast op elke ingebedde collectie.
$a
is bijvoorbeeld een array met twee elementen: een geneste array van tekenreeksen en één enkele 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 operator voor lidtoegang gebruikt, worden de items in $a
in PowerShell opgesomd en wordt de methode ToUpper()
voor alle items aangeroepen.
Notities
Zoals eerder vermeld, kunnen er subtiele gedrags- en prestatieverschillen zijn tussen de verschillende opsommingsmethoden.
Fouten resulteren in verloren uitvoer
Wanneer de opsomming van lidtoegang wordt beëindigd door een fout, wordt de uitvoer van eerdere succesvolle methodeaanroepen niet geretourneerd. Voorwaarden voor afsluitfouten zijn onder andere:
- het geïnventariseerd object ontbreekt aan de toegankelijkheidsmethode
- de geopende methode leidt tot een afsluitfout
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()
, zodat 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 array 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.