Partager via


about_Member-Access_Enumeration

Description courte

Décrit l’énumération automatique des collections lorsqu’on utilise l’opérateur d’accès aux membres.

Description longue

PowerShell maintient une liste de types énumérables. À partir de PowerShell 3.0, la fonctionnalité d’énumération par accès aux membres améliore la commodité de l’utilisation de l’opérateur d’accès aux membres (.) sur les objets de collection énumérables.

L’énumération d’accès aux membres vous aide à écrire du code plus simple et plus court. Au lieu d’acheminer un objet de collection vers ou à ForEach-Object l’aide de la ForEach()méthode intrinsèque pour accéder aux membres sur chaque élément de la collection, vous pouvez utiliser l’opérateur d’accès membre sur l’objet de collection.

Le dernier exemple illustre l’utilisation de l’opérateur d’accès aux membres : Le dernier exemple illustre l’utilisation de l’opérateur d’accès aux membres :

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

Remarque

Vous pouvez utiliser l’opérateur d’accès membre pour obtenir les valeurs d’une propriété sur les éléments d’une collection, mais vous ne pouvez pas l’utiliser pour les définir directement. Pour plus d’informations, consultez about_Arrays. L’énumération par accès aux membres est une fonctionnalité de commodité. Il peut y avoir des différences subtiles de comportement et de performance entre les différentes méthodes d’énumération.

Lorsque vous utilisez l’opérateur d’accès aux membres sur un objet et que le membre spécifié existe sur cet objet, le membre est invoqué. Lorsque vous utilisez l’opérateur d’accès aux membres sur un objet de collection qui n’a pas le membre spécifié, PowerShell énumère les éléments de cette collection et utilise l’opérateur d’accès aux membres sur chaque élément énuméré.

Pendant l’énumération d’accès membre pour une propriété, l’opérateur retourne la valeur de la propriété pour chaque élément qui a cette propriété. Si aucun élément n’a la propriété spécifiée, l’opérateur retourne $null.

Pendant l’énumération d’accès membre pour une méthode, l’opérateur tente d’appeler la méthode sur chaque élément de la collection. Si un élément de la collection n’a pas la méthode spécifiée, l’opérateur retourne l’exception MethodNotFound .

Avertissement

Pendant l’énumération d’accès membre pour une méthode, la méthode est appelée sur chaque élément de la collection. Si la méthode que vous appelez apporte des modifications, les modifications sont apportées pour chaque élément de la collection. Si une erreur se produit pendant l’énumération, la méthode est appelée uniquement sur les éléments énumérés avant l’erreur. Pour une sécurité supplémentaire, envisagez d’énumérer manuellement les éléments et de gérer explicitement les erreurs.

Accéder aux membres d’un objet non énumérable

Lorsque vous utilisez l’opérateur d’accès aux membres sur un objet qui n’est pas une collection énumérable, PowerShell invoque le membre pour retourner la valeur de la propriété ou le résultat de la méthode pour cet objet.

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

Lorsque vous utilisez l’opérateur d’accès aux membres sur un objet non énumérable qui n’a pas le membre, PowerShell retourne $null pour la propriété manquante ou une erreur MethodNotFound pour la méthode manquante.

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'.

Accéder aux membres d’une collection d’objets

Lorsque vous utilisez l’opérateur d’accès membre sur un objet de collection qui a le membre, il retourne toujours la valeur de propriété ou le résultat de la méthode pour l’objet de collection.

Accéder aux membres qui existent sur la collection mais pas sur ses éléments

Dans cet exemple, les membres spécifiés existent sur la collection, mais pas les éléments qu’il contient.

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

Accéder aux membres qui existent au sein de la collection et de ses éléments

Pour cet exemple, les membres spécifiés existent à la fois sur la collection et les éléments qu’il contient. Comparez les résultats des commandes à l’aide de l’opérateur d’accès membre sur la collection aux résultats de l’utilisation de l’opérateur d’accès membre sur les éléments de collection dans ForEach-Object. Sur la collection, l’opérateur retourne la valeur de propriété ou le résultat de la méthode pour l’objet de collection et non les éléments qu’il contient.

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

Remarque

Les collections qui implémentent l’interface System.Collections.IDictionary , comme HashTable et OrderedDictionary, ont un comportement différent. Lorsque vous utilisez l’opérateur d’accès membre sur un dictionnaire qui a une clé portant le même nom qu’une propriété, elle retourne la valeur de la clé au lieu de celle de la propriété.

Vous pouvez accéder à la valeur de propriété de l’objet dictionnaire avec le membre intrinsèque psbase. Par exemple, si le nom de clé est keys et que vous souhaitez retourner la collection des clés HashTable , utilisez cette syntaxe :

$hashtable.psbase.Keys

Accéder aux membres qui existent dans tous les éléments d’une collection, sauf à elle-même

Lorsque vous utilisez l'opérateur d'accès aux membres sur un objet de collection qui ne possède pas ce membre, mais que les éléments qu'il contient le possèdent, PowerShell énumère les éléments de la collection et retourne la valeur de la propriété ou le résultat de la méthode pour chaque élément.

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

Accéder à des membres qui n'existent pas dans la collection ou ses éléments

Lorsque vous utilisez l’opérateur d’accès aux membres sur un objet de collection qui n’a pas le membre et que les éléments non plus, la commande retourne $null si vous spécifiez une propriété ou une erreur MethodNotFound si vous spécifiez une méthode.

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'.

Étant donné que l’objet de collection n’a pas le membre, PowerShell a énuméré les éléments de la collection. Remarquez que l’erreur MethodNotFound spécifie que System.String ne contient pas la méthode au lieu de System.Collections.Generic.List.

Accéder aux méthodes qui existent uniquement sur certains éléments dans une collection

Lorsque vous utilisez l’opérateur d’accès aux membres pour accéder à une méthode sur un objet de collection qui n’a pas la méthode et que seuls certains éléments de la collection l’ont, la commande retourne une erreur MethodNotFound pour le premier élément de la collection qui n’a pas la méthode. Même si la méthode est appelée sur certains éléments, la commande retourne uniquement l’erreur.

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

Accéder aux propriétés qui existent uniquement sur certains éléments dans une collection

Lorsque vous utilisez l’opérateur d’accès aux membres pour accéder à une propriété sur un objet de collection qui n’a pas la propriété et que seuls certains éléments de la collection l’ont, la commande retourne la valeur de la propriété pour chaque élément de la collection qui possède la propriété.

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

Accéder aux membres d’une collection imbriquée

Lorsqu’une collection énumérable contient une collection imbriquée, l’énumération par accès aux membres est appliquée à chaque collection imbriquée.

Par exemple, $a est un tableau contenant deux éléments : un tableau imbriqué de chaînes de caractères et une chaîne unique.

# 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

Lorsque vous utilisez l’opérateur d’accès aux membres, PowerShell énumère les éléments dans $a et appelle la méthode ToUpper() sur tous les éléments.

Notes

Comme indiqué précédemment, il peut y avoir des différences subtiles de comportement et de performance entre les différentes méthodes d’énumération.

Les erreurs entraînent une perte de sortie

Lorsque l’énumération d’accès aux membres est interrompue en raison d'une erreur, les résultats des appels de méthode précédents réussis ne sont pas renvoyés. Les conditions d’erreur avec fin d’exécution incluent :

  • La méthode accédée manque dans l’objet énuméré.
  • la méthode accessible déclenche une erreur avec fin d’exécution

Prenons l'exemple suivant :

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())

Les deux éléments dans $example1 ont la méthode Foo(), donc l’appel de la méthode réussit.

PS> $example1.Foo()
Bar
Bar

La méthode Foo() sur le deuxième élément dans $example2 déclenche une erreur, donc l’énumération échoue.

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

Le deuxième élément dans $example2 n’a pas la méthode Foo(), donc l’énumération échoue.

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

Comparez ceci à l’énumération en utilisant 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

Notez que la sortie affiche l’appel réussi à Foo() sur le premier élément du tableau.

Collections contenant des instances de PSCustomObject

Si la collection d’objets contient des instances d’éléments PSCustomObject, PowerShell renvoie de façon inattendue des valeurs $null lorsque la propriété accessible est manquante.

Dans les exemples suivants, au moins un objet possède la propriété référencée.

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
]

Vous vous attendez à ce que PowerShell retourne un seul objet pour l’élément qui possède la propriété spécifiée. Au lieu de cela, PowerShell retourne également une valeur $null pour chaque élément qui n’a pas la propriété.

Pour plus d’informations sur ce comportement, veuillez consulter l’issue PowerShell #13752.

Voir aussi