2010-10-14 9 views
10

Pracuję nad niektórymi funkcjami PowerShell, aby zarządzać obiektami zaimplementowanymi w utworzonym przez nas złożeniu. Jedna z klas, z którymi pracowałem implementuje IEnumerable. Niestety, powoduje to, że PowerShell rozwija obiekt przy każdej okazji. (Nie mogę zmienić faktu, że klasa implementuje IEnumerable.)Spraw, aby PowerShell sądził, że obiekt nie jest wymienny.

Rozwiązałem problem, tworząc obiekt PSObject i kopiując właściwości naszego niestandardowego obiektu do obiektu PSObject, a następnie zwracając go zamiast niestandardowego obiektu . Ale wolałbym raczej zwrócić nasz niestandardowy obiekt.

Czy jest jakiś sposób, prawdopodobnie za pomocą mojego pliku types.ps1xml, aby ukryć metodę GetEnumerator() tej klasy z PowerShell (lub w inny sposób powiedzieć PowerShell, aby nigdy go nie rozwinąć).

+1

Masz niestandardową kolekcję i nie chcesz, aby Power Shell traktował ją jako kolekcję? – rerun

+1

Tak, to prawie tyle. Klasa ma rzeczy na niej inne niż kolekcja. Nie pozwól, aby to rozwinęło się w dyskusję na temat (de) zalet tego, czy klasa ta powinna być wymienna. – OldFart

Odpowiedz

8

Owijanie w PSObject jest prawdopodobnie najlepszym sposobem.

Można również jawnie zawinąć go w innej kolekcji — PowerShell tylko rozpakowuje jeden poziom.

Również podczas pisania cmdlet w C#/VB/... podczas wywoływania WriteObject użyj przeciążenia, które ma drugi parametr: jeśli false, PowerShell nie wyliczy obiekt przekazany jako pierwszy parametr.

5

Sprawdź zamiennik Write-Output http://poshcode.org/2300, który ma parametr -AsCollection, który pozwala uniknąć rozwijania. Ale w zasadzie, jeśli piszesz funkcję, która wyprowadza kolekcji, a nie chcesz, że kolekcja rozwinął, trzeba użyć CmdletBinding i PSCmdlet:

function Get-Array { 
    [CmdletBinding()] 
    Param([Switch]$AsCollection) 

    [String[]]$data = "one","two","three","four" 
    if($AsCollection) { 
     $PSCmdlet.WriteObject($data,$false) 
    } else { 
     Write-Output $data 
    } 
} 

Jeśli zadzwonisz, że będziesz z -AsCollection uzyskują bardzo różne wyniki, chociaż LOOK THE SAME w konsoli.

C:\PS> Get-Array 

one 
two 
three 
four 

C:\PS> Get-Array -AsCollection 

one 
two 
three 
four 

C:\PS> Get-Array -AsCollection| % { $_.GetType() } 


IsPublic IsSerial Name  BaseType        
-------- -------- ----  --------        
True  True  String[] System.Array       



C:\PS> Get-Array | % { $_.GetType() } 


IsPublic IsSerial Name  BaseType        
-------- -------- ----  --------        
True  True  String  System.Object       
True  True  String  System.Object       
True  True  String  System.Object       
True  True  String  System.Object 
+0

Problem polega na tym, że chcę uniknąć rozwinięcia go KIEDYKOLWIEK. Mogę zwrócić obiekt z mojej funkcji bez rozwijania go za pomocą sztuczki return-as-array (lub tego, co opisujesz). Ale ostatecznie rozwiążę to przez przypadek. – OldFart

+3

Po prostu: nie wiem, jak to zrobić, ale proszę nie próbuj :) ... Jeśli znajdziesz sposób, po prostu skończysz, powodując kilka raportów o błędach od osób, które nie są w stanie zrozumieć, dlaczego twoje kolekcja nie zawiera niczego, mimo że .Count zgłasza niezłą dużą liczbę. – Jaykul

Powiązane problemy