Project

General

Profile

Function New-GenericObject

function New-GenericObject 
      $instance = $(throw "Please provide an instance on which to invoke the generic method"), 
      [string] $methodName = $(throw "Please provide a method name to invoke"), 
      [string[]] $typeParameters = $(throw "Please specify the type parameters"), 
      [object[]] $methodParameters = @()
      )

L'usage de classe générique est malaisé dans PowerShell version 1, on doit utiliser le guillemet inverse "`" (backtick, touche "Alt Gr-7") pour préciser le type générique, cette notation est issue du système de réflexion de dotnet.

Par exemple la création d'une liste d'entier se fait de la manière suivante :

$Liste=New-Object "System.Collections.Generic.List``1[System.Int32]" 
$Liste.GetType().UnderlyingSystemType
$Liste.GetType().FullName

Le ``1 indique le nombre de paramètre attendu par le constructeur de la classe générique, ici un seul de type System.Int32.
Dans l'exemple suivant on doit en préciser deux :
$HashTable= New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]" 

Dans certains cas la syntaxe précédente ne fonctionne plus :

$Hashtable = New-Object "System.Collections.Generic.SortedDictionary``2[System.String,System.String]" 

Ce code provoque l'erreur suivante :

New-Object : Le type [System.Collections.Generic.SortedDictionary`2[System.String,System.String]] est introuvable : vérifiez que l'assembly dans lequel il se trouve est chargé.

Source
Bien qu'il soit défini dans le même espace de nom, la classe Dictionary n'est pas définie dans le même assembly que la classe SortedDictionary. L'une l'est dans mscorlib.dll et l'autre dans system.dll, là est le problème.
Lors de la résolution des noms des paramètres génériques spécifiques, PowerShell version 1 suppose par défaut qu'ils sont dans la même assembly que le type générique qu'on essaie d'instancier.

Dans ce cas, cela signifie qu'il recherche le type System.String dans System.dll et pas dans mscorlib.dll, c'est pourquoi il échoue.
La solution est de spécifier un nom fort pour les paramètres d'un type générique.


$Hashtable = new-object "System.Collections.Generic.SortedDictionary``2[
                          [System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
                          [System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
                         ]" 

L'usage de la fonction New-GenericObject facilite la création d'instances de classe générique en évitant de recourir au nom fort :
$Hashtable = New-GenericObject System.Collections.Generic.SortedDictionary System.String,System.String

Voir aussi :
PowerShell Get-Type: Simplified Generics