Question [Astuce] Copier une collection dans un tableau

Plus d'informations
il y a 14 ans 9 mois #4852 par Laurent Dardenne
Certaines collections, notamment quelques une renvoyées par les classes dotnet de gestion de WMI, ne sont pas accessible par un index :
[code:1]
#Récupère le premier disque
$Disque=gwmi Win32_DiskDrive|select -first 1
#Récupère les associations (WMI) du disque
$TempAssociations=$Disque.psbase.GetRelationships()

$TempAssociations[0]
#exception
#Impossible d'indexer dans un objet de type System.Management.ManagementObjectCollection.
[/code:1]
Cette erreur est dû au fait que la classe ManagementObjectCollection n'implémente pas l'interface IList qui elle gére les accès indexés dans une collection:
[code:1]
$TempAssociations.GetType().GetInterfaces()
# IsPublic IsSerial Name BaseType
#

----
# True False ICollection
# True False IEnumerable
# True False IDisposable
[/code:1]
On peut convertir la collection dans un tableau à l'aide de la méthode CopyTo() de l'interface ICollection :
[code:1]
if ($TempAssociations -is [System.Collections.ICollection])
{
#crée un tableau de la taille de la collection
$Associations=new-object Object[] $TempAssociations.count
#On recopie la collection dans le tableau à partir de l'index 0
$TempAssociations.CopyTo($Associations,0)
}
else {Write-Warning \"L'objet n'implémente pas l'interface ICollection\"}

#On supprime la collection inutile
$TempAssociations.Dispose()
$TempAssociations=$Null
$Associations[0]
[/code:1]

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 mois #13153 par Laurent Dardenne
Pour info, le comportement est différent avec la Version 3 de Powershell, le code ne génère plus d'exception.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 mois #13274 par Matthew BETTON
Salut,

Laurent Dardenne écrit:

Pour info, le comportement est différent avec la Version 3 de Powershell, le code ne génère plus d'exception.


Le code ne génère plus d'erreur... il ne renvoie pas non plus le premier élément mais toute la collection ;)

Merci Laurent

@ +

Matthew

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 mois #13278 par Laurent Dardenne
Matthew BETTON écrit:

il ne renvoie pas non plus le premier élément mais toute la collection

C'est vrai, je n'avais pas remarqué, mais étant dans un comportment liè à une interface, je ne suis pas plus surpris que ça, mais tu fais bien de le préciser.

Ensuite d'expliquer ça, je te laisse la main :whistle:
C'est pas évident, voir accessoire.

Sinon on peut demander aux formateurs PowerShell. Alors donc, une idée ?

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 mois #13284 par Matthew BETTON
Laurent Dardenne écrit:

Matthew BETTON écrit:

il ne renvoie pas non plus le premier élément mais toute la collection

Ensuite d'expliquer ça, je te laisse la main :whistle:


Et bien.. Je ne vois pas, d'autant plus que la propriété 'count' renvoie bien le nombre d'éléments :

[code:1]$TempAssociations.count
#6 (dans mon cas, bien entendu)[/code:1]

Alors là, je deviens bigleux... Je suis dans le \"cloud\" !

Ce comportement reste une énigme (pour moi ?).

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 mois #13301 par Laurent Dardenne
Effectivement, il faut revenir aux sources.
Matthew BETTON écrit:

il ne renvoie pas non plus le premier élément mais toute la collection ;)

Avec PS v2 :
[code:1]
(1)[0]
[ : Impossible d'indexer dans un objet de type System.Int32.
[/code:1]
On obtient une exception, si on indexe une type qui ne peut l'être.
Avec PS v3 :
[code:1]
(1)[0]
1
[/code:1]
On obtient la valeur, sans déclenchement d'exception.

Donc, le premier post de ce thread ( $TempAssociations[0] ) est tjr cohérent avec la V2.

Ce qu'on peut constater est que ce n'est pas parce que le parseur accepte une syntaxe indexée ( la présence de [] ) sur une collection que celle-ci peut l'être.
PS v3 ajoute un couche ( de confusion ?) en donnant l'impression qu'on peut tout indexer, bien qu'il reste une logique ($null[0] n'est pas autorisé).

Pour tester le comportement d'indexation sur une collection voir ce post .
L'appel de
[code:1]
Test-AccessedByIndex $TempAssociations
[/code:1]
sur les deux versions renvoit False. Donc là, si on adresse le comportement, porté par l'interface IList, on est assuré du résultat, cette variable ne peut être indexée.

Ici on n'adresse pas le parseur PS , mais le framework dotNET, bye bye les farceurs...
Matthew BETTON écrit:

d'autant plus que la propriété 'count' renvoie bien le nombre d'éléments

Oui, tu as raison, remarque que tu utilises le terme de 'propriété', l'information existe. L'indexation est un comportement, une possibilité de manipulation.
Une propriété existe ou pas.

En dotNET, une collection de données peut implémenter un ou plusieurs comportements, toute collection est au moins un ensemble de données (on laisse de côtè les ensembles vide).
Un ensemble de données peut ne pas être ordonnées, exemple les hashtables ( @{} ), voir ne pas être 'itérable à volonté' (pas sûr du terme).

Exemple issu de mon tutoriel Powershell sur le pipeline :
[code:1]
Function MaFonction
{
Write-host \"`tDonnées dans la fonction2-1 : $input\" -F Yellow
Write-host \"`tEt l'écho répond : Données dans la fonction2-1 : $input\" -F Green

}
1..3|MaFonction
[/code:1]
Ici $Input est une collection, mais sa première itération place un curseur interne sur la fin de la collection.
Le fait d'adresser à nouveau cette collection, ne renvoie rien, normal une fois le 'curseur' en fin, on ne peut aller au delà.

Essayons autre chose :
[code:1]
Function MaFonction
{
Write-host \"`tDonnées dans la fonction2-1 : $input\" -F Yellow
$Input.Reset()
Write-host \"`tEt l'écho répond : Données dans la fonction2-1 : $input\" -F Green
}
1..3|MaFonction
[/code:1]
Ici le fait de replacer le curseur au 'début', permet de corriger le pb d'affichage.
Je te laisse digérer ça, en espérant t'avoir apporté qq lumières.<br><br>Message édité par: Laurent Dardenne, à: 12/12/12 17:36

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.080 secondes
Propulsé par Kunena