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