Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic type of Generic Type in Powershell

Tags:

powershell

Well generics in Powershel are quite confusing. To instantiate a simple List you need to dance around with a tambourine:

$type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
$type= $type.MakeGenericType("System.string" -as "Type")
$o = [Activator]::CreateInstance($type)

But what if I need something a bit more complex like: <Dictionary<string,List<Foo>> for example

or for example here: Dictionary<string,List<string>>

$listType = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
$listType = $listType.MakeGenericType("System.string" -as "Type")
$L = [Activator]::CreateInstance($listType)

$dicType = ("System.Collections.Generic.Dictionary"+'`'+"2") -as "Type"

#the next line is problematic
$dicType = $dicType.MakeGenericType( 
     @( ("system.string" -as "Type"), 
        ("System.Collections.Generic.List" as "Type)) # and that's of course wrong
      )

$D = [Activator]::CreateInstance($dicType )
like image 447
iLemming Avatar asked Aug 15 '12 18:08

iLemming


People also ask

How do you find the type of generic type?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.

What is the generic class type called?

Generic Classes These classes are known as parameterized classes or parameterized types because they accept one or more parameters.

What is a generic type parameter?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.


1 Answers

While you can delve into CLR internal representations and make life hard for yourself, you don't have to:

$dict = new-object 'collections.generic.dictionary[string,int]'
$dict.add("answer", 42)

Want a type literal representation?

[collections.generic.dictonary[string,int]]

Done. How about generic type parameters?

$dictOfList = new-object 'collections.generic.dictionary[string,
    [collections.generic.list[int]]]'

Done.

However, there's an unfortunate catch. In PowerShell 2.0, there's a bug when you mix and match BCL and 3rd party types as type parameters. The latter need to be assembly qualified:

# broken over two lines for clarity with backtick escape
$o = new-object ('collections.generic.dictionary[[{0}],[{1}]]' -f `
        [type1].fullname, [type2].fullname)

Hope this helps. In PowerShell 3.0, this has been fixed.

like image 130
x0n Avatar answered Oct 10 '22 10:10

x0n