Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Krótki opis
Opisuje automatyczne wyliczanie kolekcji podczas używania operatora dostępu do elementów.
Długi opis
Program PowerShell utrzymuje listę typów, które są wyliczane. Począwszy od programu PowerShell 3.0, funkcja wyliczania dostępu do
Wyliczenie dostępu do składowych ułatwia pisanie prostszego i krótszego kodu. Zamiast potokować obiekt kolekcji do obiektu kolekcji lub używając ForEach-Object
ForEach()
wewnętrznej w celu uzyskania dostępu do elementów członkowskich w każdej kolekcji, można użyć operatora dostępu do elementu członkowskiego w obiekcie kolekcji.
W poniższych przykładach przedstawiono te same wyniki. W ostatnim przykładzie pokazano użycie operatora dostępu członka:
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
Uwaga
Możesz użyć operatora dostępu do elementu członkowskiego, aby pobrać wartości właściwości w elementach w kolekcji, ale nie można jej użyć do ich bezpośredniego ustawienia. Aby uzyskać więcej informacji, zobacz about_Arrays. Wyliczenie dostępu do składowych jest funkcją wygody. Mogą istnieć subtelne zachowania i różnice wydajności między różnymi metodami wyliczania.
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie i określony element członkowski istnieje w tym obiekcie, element członkowski jest wywoływany. Jeśli używasz operatora dostępu do członkowskiego na obiekcie kolekcji, który nie ma określonego elementu członkowskiego, PowerShell enumeruje elementy w tej kolekcji i używa operatora dostępu do członkowskiego na każdym wyliczonym elemencie.
Podczas wyliczania dostępu do elementu członkowskiego dla właściwości operator zwraca wartość właściwości dla każdego elementu, który ma ta właściwość. Jeśli żadne elementy nie mają określonej właściwości, operator zwraca wartość $null
.
Podczas wyliczania dostępu do elementu członkowskiego dla metody operator próbuje wywołać metodę dla każdego elementu w kolekcji. Jeśli którykolwiek element w kolekcji nie ma określonej metody, operator zwraca wyjątek MethodNotFound .
Ostrzeżenie
Podczas wyliczania dostępu do składowych dla metody metoda jest wywoływana dla każdego elementu w kolekcji. Jeśli wywoływana metoda wprowadza zmiany, zmiany są wprowadzane dla każdego elementu w kolekcji. Jeśli podczas wyliczania wystąpi błąd, metoda jest wywoływana tylko na elementach wyliczonych przed błędem. Aby uzyskać dodatkowe bezpieczeństwo, rozważ ręczne wyliczanie elementów i jawne obsługiwanie błędów.
Uzyskiwanie dostępu do elementów składowych obiektu nienumerowalnego
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie, który nie jest kolekcją wyliczalną, program PowerShell wywołuje element członkowski w celu zwracania wartości właściwości lub danych wyjściowych metody dla tego obiektu.
PS> $MyString = 'abc'
PS> $MyString.Length
3
PS> $MyString.ToUpper()
ABC
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie nieliczalnym, który nie ma elementu członkowskiego, program PowerShell zwraca $null
dla brakującej właściwości lub błąd MethodNotFound dla brakującej metody.
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
Uzyskiwanie dostępu do członków obiektu kolekcji
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie kolekcji, który ma element członkowski, zawsze zwraca wartość właściwości lub wynik metody dla obiektu kolekcji.
Dostęp do elementów członkowskich, które istnieją w kolekcji, ale nie jej elementów
W tym przykładzie określone elementy członkowskie istnieją w kolekcji, ale nie w niej.
PS> [System.Collections.Generic.List[string]]$Collection = @('a', 'b')
PS> $Collection.IsReadOnly
False
PS> $Collection.Add('c')
PS> $Collection
a
b
c
Dostęp do członków istniejących w kolekcji i jej elementach
W tym przykładzie określone elementy członkowskie istnieją zarówno w kolekcji, jak i w niej elementach. Porównaj wyniki poleceń przy użyciu operatora dostępu elementu członkowskiego w kolekcji do wyników przy użyciu operatora dostępu do elementu członkowskiego w elementach kolekcji w ForEach-Object
programie . W kolekcji operator zwraca wartość właściwości lub wynik metody dla obiektu kolekcji, a nie elementy w nim.
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
Uwaga
Kolekcje implementujące interfejs System.Collections.IDictionary , takie jak HashTable i OrderedDictionary, mają inne zachowanie. Jeśli używasz operatora dostępu do elementu członkowskiego w słowniku, który ma klucz o takiej samej nazwie jak właściwość, zwraca wartość klucza zamiast właściwości.
Dostęp do wartości właściwości obiektu słownika można uzyskać za pomocą wewnętrznego elementu członkowskiego psbase. Jeśli na przykład nazwa klucza to keys
i chcesz zwrócić kolekcję kluczy HashTable , użyj następującej składni:
$hashtable.psbase.Keys
Dostęp do członków, którzy istnieją we wszystkich elementach w kolekcji, ale nie w niej samej.
Jeśli używasz operatora dostępu do członków w obiekcie kolekcji, który nie ma tego członka, lecz elementy w niej go mają, PowerShell wylicza te elementy i zwraca wartość właściwości lub wynik metody dla każdego elementu.
PS> [System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
PS> $Collection.Length
1
1
1
PS> $Collection.ToUpper()
A
B
C
Dostęp do członków, które nie istnieją w zbiorze lub jego elementach
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie kolekcji, który nie zawiera danego elementu członkowskiego, ani nie zawierają go jego elementy, polecenie zwraca $null
, jeśli określisz właściwość, lub błąd MethodNotFound
, jeśli określisz metodę.
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'.
Ponieważ obiekt kolekcji nie zawiera członka, program PowerShell wyliczył elementy w kolekcji. Zauważ, że błąd MethodNotFound określa, że System.String nie zawiera metody zamiast System.Collections.Generic.List.
Metody dostępu, które istnieją tylko w niektórych elementach w kolekcji
Jeśli używasz operatora dostępu do elementu członkowskiego, aby uzyskać dostęp do metody w obiekcie kolekcji, która nie ma tej metody, i tylko niektóre elementy w tej kolekcji mają ją, polecenie zwraca błąd MethodNotFound
dla pierwszego elementu w kolekcji, który nie ma metody. Mimo że metoda jest wywoływana dla niektórych elementów, polecenie zwraca tylko błąd.
PS> @('a', 1, 'c').ToUpper()
InvalidOperation: Method invocation failed because [System.Int32] does not
contain a method named 'ToUpper'.
Dostęp do właściwości, które istnieją tylko dla niektórych elementów w kolekcji
Jeśli używasz operatora dostępu do elementu członkowskiego, aby uzyskać dostęp do właściwości w obiekcie kolekcji, który nie ma właściwości, a tylko niektóre elementy w kolekcji mają ją, polecenie zwraca wartość właściwości dla każdego elementu w kolekcji, który ma właściwość.
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
Uzyskiwanie dostępu do elementów zagnieżdżonej kolekcji
Gdy kolekcja wyliczalna zawiera zagnieżdżoną kolekcję, enumeracja dostępu do elementów jest stosowana do każdej zagnieżdżonej kolekcji.
Na przykład $a
to tablica zawierająca dwa elementy: zagnieżdżona tablica ciągów i pojedynczy ciąg.
# 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
W przypadku korzystania z operatora dostępu do składowych program PowerShell wylicza elementy w $a
i wywołuje metodę ToUpper()
we wszystkich elementach.
Notatki
Jak wspomniano wcześniej, mogą istnieć subtelne zachowania i różnice wydajności między różnymi metodami wyliczania.
Błędy powodują utratę danych wyjściowych
Gdy wyliczenie dostępu do elementu członkowskiego zostanie zakończone przez błąd, dane wyjściowe z poprzednich pomyślnych wywołań metody nie zostaną zwrócone. Warunki błędu zakończenia obejmują:
- wyliczony obiekt nie ma metody dostępnej
- metoda, do której uzyskano dostęp, zgłasza błąd krytyczny
Rozważmy następujący przykład:
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())
Oba elementy w $example1
mają metodę Foo()
, więc wywołanie metody powiedzie się.
PS> $example1.Foo()
Bar
Bar
Metoda Foo()
w drugim elemencie w $example2
zgłasza błąd, więc wyliczenie kończy się niepowodzeniem.
PS> $example2.Foo()
Exception:
Line |
2 | class Class2 { [void] Foo() { throw 'Error' } }
| ~~~~~~~~~~~~~
| Error
Drugi element w $example2
nie ma metody Foo()
, więc wyliczenie kończy się niepowodzeniem.
PS> $example3.Foo()
InvalidOperation: Method invocation failed because [Class3] does not contain
a method named 'Foo'.
Porównaj to z wyliczeniem przy użyciu 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
Zwróć uwagę, że dane wyjściowe pokazują pomyślne wywołanie Foo()
na pierwszym elemencie w tablicy.
Kolekcje zawierające wystąpienia obiektu PSCustomObject
Jeśli kolekcja obiektów zawiera wystąpienia elementów PSCustomObject, program PowerShell nieoczekiwanie zwraca $null
wartości, gdy właściwość, do której uzyskano dostęp, jest brakująca.
W poniższych przykładach co najmniej jeden obiekt ma przywołyną właściwość.
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
]
Oczekuje się, że program PowerShell zwróci pojedynczy obiekt dla elementu, który ma określoną właściwość. Zamiast tego program PowerShell zwraca również wartość $null
dla każdego elementu, który nie ma właściwości.
Aby uzyskać więcej informacji na temat tego zachowania, zobacz Problem z programem PowerShell #13752.