Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Krótki opis
Opisuje automatyczne wyliczanie kolekcji podczas korzystania z operatora dostępu do składowych.
Długi opis
Program PowerShell utrzymuje listę typów, które są wyliczane. Od wersji PowerShell 3.0 funkcja wyliczania dostępu do elementu członkowskiego ułatwia korzystanie z operatora dostępu do elementów członkowskich (.) w obiektach kolekcji będących wyliczalnymi.
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-ObjectForEach() 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. Enumeracja dostępu do członków jest ułatwiającą funkcją. Mogą istnieć subtelne zachowania i różnice wydajności między różnymi metodami wyliczania.
Jeśli używasz operatora dostępu do składnika w obiekcie i określony składnik istnieje w tym obiekcie, zostaje wywołany. Jeśli używasz operatora dostępu do składowej w obiekcie kolekcji, który nie ma określonej składowej, program PowerShell przechodzi przez elementy tej kolekcji i używa operatora dostępu do składowej w 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 członkowskich 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()
InvalidOperation: Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.
Uzyskiwanie dostępu do elementów członkowskich 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 członków istniejących w kolekcji, ale nie w jej elementach
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, które istnieją 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-Objectprogramie . 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 elementów członkowskich, które istnieją we wszystkich elementach w zbiorze, ale nie w nim samym
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie kolekcji, który nie ma elementu członkowskiego, ale elementy w nim działają, program PowerShell wylicza elementy w kolekcji 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 elementów członkowskich, które nie istnieją w kolekcji lub jej elementach
Jeśli używasz operatora dostępu do elementu członkowskiego w obiekcie kolekcji, który nie ma elementu członkowskiego i nie ma w nim elementów, polecenie zwraca $null, jeśli określisz właściwość lub MethodNotFound błąd, 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 ma elementu członkowskiego, program PowerShell wyliczał 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 członka, aby uzyskać dostęp do metody w obiekcie kolekcji, który nie ma tej metody, a tylko niektóre elementy w kolekcji ją mają, polecenie zwraca błąd MethodNotFound dla pierwszego elementu w kolekcji, który tej metody nie ma. 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 posiada tej właściwości, a tylko niektóre elementy w kolekcji ją mają, polecenie zwraca wartość tej właściwości dla każdego elementu w kolekcji, który ją posiada.
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 użycia operatora dostępu do składowych PowerShell przetwarza elementy w $a i wywołuje metodę ToUpper() dla wszystkich elementów.
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 wyliczanie dostępu do członka zostanie zakończone z powodu błędu, wyniki poprzednich, pomyślnych wywołań metody nie są zwracane. Warunki błędu zakończenia obejmują:
- wyliczony obiekt nie ma metody dostępnej
- metoda, do której uzyskano dostęp, zgłasza krytyczny błąd
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 powiodło 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 wartości $null, jeśli brak wymaganej właściwości.
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.