2010-10-14 11 views
10

He estado trabajando en algunas funciones de PowerShell para administrar objetos implementados en un ensamblado que hemos creado. Una de las clases con las que he estado trabajando implementa IEnumerable. Desgraciadamente, esto hace que PowerShell desenrolle el objeto en cada oportunidad. (No puedo cambiar el hecho de que la clase implementa IEnumerable.)Hacer que PowerShell piense que un objeto no es enumerable

He solucionado el problema creando un PSObject y copiando las propiedades de nuestro objeto personalizado en el PSObject, y luego devolviendo eso en lugar del objeto personalizado . Pero prefiero devolver nuestro objeto personalizado.

¿Hay alguna manera, supuestamente utilizando mi archivo types.ps1xml, para ocultar el método GetEnumerator() de esta clase de PowerShell (o decirle a PowerShell que nunca lo desenrolle).

+1

lo que tiene una clase de colección personalizada y no quieres PowerShell para tratarla como una colección? – rerun

+1

Sí, eso es más o menos. La clase tiene cosas que no sean la colección. No permita que esto pase a ser una discusión sobre los (de) méritos de si esta clase debe ser enumerable o no. – OldFart

Respuesta

8

Envolver en un PSObject es probablemente la mejor manera.

También podría envolverlo explícitamente en otra colección — PowerShell solo desenvuelve un nivel.

Además, al escribir un cmdlet en C#/VB/... cuando llame al WriteObject use la sobrecarga que toma un segundo parámetro: si es falso, PowerShell no enumerará el objeto pasado como el primer parámetro.

5

Comprueba la sustitución de escritura de salida http://poshcode.org/2300 que tiene un parámetro -AsCollection que te permite evitar el desenrollado. Pero, básicamente, si usted está escribiendo una función que da salida a una colección, y que no desea que la recolección de desenrollado, es necesario utilizar CmdletBinding y PSCmdlet:

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

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

si se llama a eso con -AsCollection podrás obtener resultados muy diferentes, aunque ellos MIRARÁN LO MISMO en la consola.

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

El problema es que quiero evitar que se desenrolle NUNCA. Puedo devolver el objeto desde mi función sin desenrollarlo utilizando el truco de retorno como matriz (o lo que describes). Pero eventualmente terminaré desenrollándolo por accidente. – OldFart

+3

En pocas palabras: no conozco ninguna manera de hacerlo, pero no intentes :) ... Si encuentras una manera, terminarás causando un montón de informes de errores de personas que no pueden entender por qué tu la colección no tiene nada, aunque .Count informa de un gran número. – Jaykul

Cuestiones relacionadas