2008-10-08 15 views
35

Pchałam się do środowiska .NET w PowerShell i trafiłam w coś, czego nie rozumiem. Działa to dobrze:Ogólne kolekcje PowerShell

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

Key               Value 
---               ----- 
FOO               BAR 

To jednak nie:

$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]" 

Oboje są w tym samym zespole, więc co mi brakuje?

Jak podkreślono w odpowiedziach, jest to tylko problem z PowerShell v1.

Odpowiedz

17

Słownik < K, V> nie jest zdefiniowany w tym samym zespole, co SortedDictionary < K, V>. Jeden jest w mscorlib, a drugi w system.dll.

Na tym polega problem. Obecne zachowanie w programie PowerShell polega na tym, że podczas rozwiązywania podanych ogólnych parametrów, jeśli typy nie są pełnymi nazwami typów, zakłada się, że są one w tym samym zespole, co typowy typ, który próbujesz utworzyć.

W tym przypadku oznacza to, że szuka System.String w System.dll, a nie w mscorlib, więc nie powiedzie się.

Rozwiązaniem jest określenie w pełni kwalifikowanej nazwy zespołu dla ogólnych typów parametrów. Jest to bardzo brzydki, ale działa:

$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]]" 
+0

Czy istnieje odniesienie opisujące tę składnię? Próbuję zaimplementować BeginInvoke z obiektu Powershell i mieć trochę czasu z wykorzystaniem parametrów wejściowych i wyjściowych w jednym z przeciążeń dla niego. Po prostu nie wydaje mi się, żeby ta deklaracja była właściwa. –

4

Występują pewne problemy z Generics w PowerShell. Lee Holmes, twórca zespołu PowerShell, opublikował this script, aby stworzyć generics.

+2

[buforowane link] (https://web.archive.org/web/20090926122811 /http://www.leeholmes.com/blog/CreatingGenericTypesInPowerShell.aspx) – user2426679

+1

Czy to jeszcze "ten wieczór"? :) – mklement0

78

W PowerShell 2.0 nowy sposób tworzenia Dictionary jest:

$object = New-Object 'system.collections.generic.dictionary[string,int]' 
+0

+1 Znacznie lepsza odpowiedź – galaktor

+7

To prawda, że ​​jest to o wiele lepsza odpowiedź. ** Jeśli ** użytkownik jest na v2. Pytanie zadano jednak w odniesieniu do wersji 1. Na świecie nadal jest duża liczba osób na v1. – EBGreen

+0

Oczywiście, ten sam problem będzie występował w wersji 2, jeśli jeden z typów zostanie zadeklarowany w zestawie innej firmy: http://stackoverflow.com/questions/11975130. Wydaje się, że zostało to naprawione w wersji 4 – marsze