Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell generic collections

I have been pushing into the .NET framework in PowerShell, and I have hit something that I don't understand. This works fine:

$foo = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]" $foo.Add("FOO", "BAR") $foo  Key                                                         Value ---                                                         ----- FOO                                                         BAR 

This however does not:

$bar = New-Object "System.Collections.Generic.SortedDictionary``2[System.String,System.String]" New-Object : Cannot find type [System.Collections.Generic.SortedDictionary`2[System.String,System.String]]: make sure t he assembly containing this type is loaded. At line:1 char:18 + $bar = New-Object <<<< "System.Collections.Generic.SortedDictionary``2[System.String,System.String]" 

They are both in the same assembly, so what am I missing?

As was pointed out in the answers, this is pretty much only an issue with PowerShell v1.

like image 781
EBGreen Avatar asked Oct 08 '08 19:10

EBGreen


People also ask

What are generic collections?

The generic collections are introduced in Java 5 Version. The generic collections disable the type-casting and there is no use of type-casting when it is used in generics. The generic collections are type-safe and checked at compile-time. These generic collections allow the datatypes to pass as parameters to classes.

What is collection in PowerShell?

Collections (Arrays) Collections are everywhere in PowerShell; they are the most prevalent of all its data structures. Cmdlets and pipes let you pass around objects, but keep in mind that they usually pass around objects (plural), not just an object (singular).

Which namespace provide the non-generic collection classes?

Collections namespace contains the non-generic collection types and System.

How do you create a dictionary in PowerShell?

Creating Ordered Dictionaries You can create an ordered dictionary by adding an object of the OrderedDictionary type, but the easiest way to create an ordered dictionary is use the [ordered] attribute. The [ordered] attribute is introduced in PowerShell 3.0. Place the attribute immediately before the "@" symbol.


2 Answers

In PowerShell 2.0 the new way to create a Dictionary is:

$object = New-Object 'system.collections.generic.dictionary[string,int]' 
like image 90
ShanePowser Avatar answered Oct 02 '22 07:10

ShanePowser


Dictionary<K,V> is not defined in the same assembly as SortedDictionary<K,V>. One is in mscorlib and the other in system.dll.

Therein lies the problem. The current behavior in PowerShell is that when resolving the generic parameters specified, if the types are not fully qualified type names, it sort of assumes that they are in the same assembly as the generic type you're trying to instantiate.

In this case, it means it's looking for System.String in System.dll, and not in mscorlib, so it fails.

The solution is to specify the fully qualified assembly name for the generic parameter types. It's extremely ugly, but works:

$bar = new-object "System.Collections.Generic.Dictionary``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]]" 
like image 35
tomasr Avatar answered Oct 02 '22 08:10

tomasr