Compartilhar via


about_Member-Access_Enumeration

Descrição breve

Descreve a enumeração automática de itens de coleção de lista ao usar o operador de acesso de membro.

Descrição longa

A partir do PowerShell 3.0, o recurso de enumeração de acesso de membro melhora a conveniência de usar o operador de acesso de membro (.) em objetos de coleção de listas. Quando você usa o operador de acesso de membro para acessar um membro que não existe em uma coleção, o PowerShell enumera automaticamente os itens na coleção e tenta acessar o membro especificado em cada item.

A enumeração de acesso de membro ajuda você a escrever um código mais simples e mais curto. Em vez de canalizar um objeto de coleção ou ForEach-Object usar o ForEach()método intrínseco para acessar membros em cada item da coleção, você pode usar o operador de acesso de membro no objeto de coleção.

Esses comandos são funcionalmente idênticos ao último que demonstra o uso do operador de acesso de membro:

Get-Service -Name event* | ForEach-Object -Process { $_.DisplayName }
(Get-Service -Name event*).ForEach({ $_.DisplayName })
(Get-Service -Name event*).DisplayName
Windows Event Log
COM+ Event System

Windows Event Log
COM+ Event System

Windows Event Log
COM+ Event System

Observação

Você pode usar o operador de acesso de membro para obter os valores de uma propriedade em itens em uma coleção, mas não pode usá-lo para defini-los diretamente. Para obter mais informações, consulte about_Arrays.

Quando você usa o operador de acesso de membro em qualquer objeto e o membro especificado existe nesse objeto, o membro é invocado. Para membros da propriedade, o operador retorna o valor dessa propriedade. Para membros do método, o operador chama esse método no objeto.

Quando você usa o operador de acesso de membro em um objeto de coleção de listas que não tem o membro especificado, o PowerShell enumera automaticamente os itens nessa coleção e usa o operador de acesso de membro em cada item enumerado.

Você pode verificar se um objeto é uma coleção de listas verificando se seu tipo implementa a interface IList :

$List = @('a', 'b')
$Hash = @{ a = 'b' }
$List.GetType().ImplementedInterfaces.Name -contains 'IList'
$Hash.GetType().ImplementedInterfaces.Name -contains 'IList'
True

False

Durante a enumeração de acesso de membro para uma propriedade, o operador retorna o valor da propriedade para cada item que tem essa propriedade. Se nenhum item tiver a propriedade especificada, o operador retornará $null.

Durante a enumeração de acesso de membro para um método, o operador tenta chamar o método em cada item da coleção. Se algum item na coleção não tiver o método especificado, o operador retornará a exceção MethodNotFound .

Aviso

Durante a enumeração de acesso de membro para um método, o método é chamado em cada item da coleção. Se o método que você está chamando fizer alterações, as alterações serão feitas para cada item na coleção. Se ocorrer um erro durante a enumeração, o método será chamado somente nos itens enumerados antes do erro. Para segurança adicional, considere enumerar manualmente os itens e tratar explicitamente quaisquer erros.

Os exemplos a seguir detalham o comportamento do operador de acesso de membro em todos os cenários possíveis.

Acessando membros de um objeto que não é de lista

Quando você usa o operador de acesso de membro em um objeto que não é uma coleção de listas e que tem o membro, o comando retorna o valor da propriedade ou saída do método para esse objeto.

$MyString = 'abc'
$MyString.Length
$MyString.ToUpper()
3

ABC

Quando você usa o operador de acesso de membro em um objeto que não é de lista que não tem o membro, o comando retorna $null se você especificar uma propriedade ou um erro MethodNotFound se você especificar um método.

$MyString = 'abc'
$null -eq $MyString.DoesNotExist
$MyString.DoesNotExist()
True

InvalidOperation:
Line |
   3 |  $MyString.DoesNotExist()
     |  ~~~~~~~~~~~~~~~~~~~~~~~~
     | Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.

Acessando membros de um objeto de coleção de listas

Quando você usa o operador de acesso ao membro em um objeto de coleção que tem o membro, ele sempre retorna o valor da propriedade ou o resultado do método para o objeto de coleção.

Acessando membros que existem na coleção, mas não seus itens

Neste exemplo, os membros especificados existem na coleção, mas não os itens nela.

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

a
b
c

Acessando membros que existem na coleção e seus itens

Para este exemplo, os membros especificados existem na coleção e nos itens nela. Compare os resultados dos comandos usando o operador de acesso de membro na coleção com os resultados do uso do operador de acesso de membro nos itens de coleção em ForEach-Object. Na coleção, o operador retorna o valor da propriedade ou o resultado do método para o objeto de coleção e não os itens nele.

[System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
$Collection.Count
$Collection | ForEach-Object -Process { $_.Count }
$Collection.ToString()
$Collection | ForEach-Object -Process { $_.ToString() }
3

1
1
1

System.Collections.Generic.List`1[System.String]

a
b
c

Observação

As coleções que implementam a interface System.Collections.IDictionary , como HashTable e OrderedDictionary, têm um comportamento diferente. Quando você usa o operador de acesso de membro em um dicionário que tem uma chave com o mesmo nome de uma propriedade, ele retorna o valor da chave em vez do valor da propriedade.

Você pode acessar o valor da propriedade do objeto de dicionário com o membro intrínseco psbase. Por exemplo, se o nome da chave for keys e você quiser retornar a coleção das chaves HashTable , use esta sintaxe:

$hashtable.PSBase.Keys

Acessando membros que existem em todos os itens de uma coleção, mas não em si mesmo

Quando você usa o operador de acesso de membro em um objeto de coleção que não tem o membro, mas os itens nele têm, o PowerShell enumera os itens na coleção e retorna o valor da propriedade ou o resultado do método para cada item.

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

A
B
C

Acessando membros que não existem na coleção nem em seus itens

Quando você usa o operador de acesso de membro em um objeto de coleção que não tem o membro e nem os itens nele, o comando retorna $null se você especificar uma propriedade ou um MethodNotFound erro se você especificar um método.

[System.Collections.Generic.List[string]]$Collection = @('a', 'b', 'c')
$null -eq $Collection.DoesNotExist
$Collection.DoesNotExist()
True

InvalidOperation:
Line |
   3 |  $Collection.DoesNotExist()
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Method invocation failed because [System.String] does not contain a method named 'DoesNotExist'.

Como o objeto de coleção não tem o membro, o PowerShell enumerou os itens na coleção. Observe que o erro MethodNotFound especifica que System.String não contém o método em vez de System.Collections.Generic.List.

Acessando métodos que existem apenas em alguns itens em uma coleção

Quando você usa o operador de acesso de membro para acessar um método em um objeto de coleção que não tem o método e apenas alguns dos itens da coleção o têm, o comando retorna um MethodNotFound erro para o primeiro item da coleção que não tem o método. Mesmo que o método seja chamado em alguns itens, o comando retorna apenas o erro.

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

Acessando propriedades que existem apenas em alguns itens em uma coleção

Quando você usa o operador de acesso de membro para acessar uma propriedade em um objeto de coleção que não tem a propriedade e apenas alguns dos itens da coleção a têm, o comando retorna o valor da propriedade para cada item na coleção que tem a propriedade.

$CapitalizedProperty = @{
    MemberType = 'ScriptProperty'
    Name       = 'Capitalized'
    Value      = { $this.ToUpper() }
    PassThru   = $true
}
[System.Collections.Generic.List[object]]$MixedCollection = @(
    'a'
    ('b' | Add-Member @CapitalizedProperty)
    ('c' | Add-Member @CapitalizedProperty)
    'd'
)
$MixedCollection.Capitalized
B
C

Confira também