2009-07-29 9 views
5

En PowerShell 1.0, si tengo un parámetro de cmdlet de tipo enum, ¿cuál es el método recomendado para probar si el usuario especificó ese parámetro en la línea de comandos del cmdlet? Por ejemplo:¿Cómo puedo determinar si se especificó un valor del parámetro Cmdlet de PowerShell?

MyEnum : int { No = 0, Yes = 1, MaybeSo = 2 } 

class DoSomethingCommand : PSCmdlet 
... 
private MyEnum isEnabled; 

[Parameter(Mandatory = false)] 
public MyEnum IsEnabled 
{ 
    get { return isEnabled; } 
    set { isEnabled = value; } 
} 

protected override void ProcessRecord() 
{ 
    // How do I know if the user passed -IsEnabled <value> to the cmdlet? 
} 

¿Hay alguna manera de hacer esto sin tener que sembrar isEnabled con un valor ficticio? Por defecto, será igual a 0, y no quiero tener que sembrar cada parámetro ni agregar un valor ficticio a mi enumeración. Tengo potencialmente muchos cmdlets con cientos de parámetros, tiene que haber una mejor manera. Esto está relacionado con this question pero estaba buscando una forma más limpia de hacerlo. Gracias.

+0

@Jack paja Si ha "potencialmente tiene muchos cmdlets con 100 de los parámetros", es posible que desee mirar a romper algo de esa funcionalidad para arriba. Uno de los beneficios clave de PowerShell es la capacidad de descubrimiento y tener un gran número de parámetros hace que el autodescubrimiento sea mucho más difícil. –

+0

@Steven, lo siento, puede haber sido engañoso; no es que cada cmdlet tenga 100 de params :), sino muchos cmdlets que dan como resultado muchos parámetros. Gracias por tu comentario. –

Respuesta

8

En este caso, me gustaría utilizar un envoltorio anulable alrededor del tipo de enumeración por ejemplo

[Parameter(Mandatory = false)] 
public MyEnum? IsEnabled { get; set; } 

¿Nota? modificador en MyEnum. A continuación, puede probar si se establece de este modo:

if (this.IsEnabled.HasValue) { ... } 
+0

Eso es exactamente lo que estaba buscando. Gracias. De hecho, hice la variable local, no la propiedad el tipo anulable, que también funciona. –

1

Lo único que puedo ver es modificar tu enumeración para que el valor 0 se llame Desconocido o algo así.

El problema es que las enumeraciones son solo enteros en el fondo y los enteros son tipos de valores. La consecuencia desafortunada es que necesitan tener valor y ese valor es 0 por defecto.

+0

@Josip, gracias, ya veo el punto. Ver mi comentario a x0n. –

4

PowerShell aparte, nunca es un buen estilo usar 0 de esa manera. Siempre debe usar 0 para el valor predeterminado más apropiado. En este caso, el valor predeterminado más apropiado debería ser algo así como "Unset".

En última instancia, esto no tiene nada que ver con PowerShell y todo tiene que ver con buenas prácticas de codificación para .NET.

  • Oisin
+0

@ x0n: Gracias por su respuesta. Si usar 0 o no para valores enum es un punto discutible, pero de cualquier manera mi producto existente tiene muchos valores 0 para enumeraciones. Supongo que mi pregunta más amplia es, ¿es este el patrón que utilizan los desarrolladores de cmdlet en esta situación? Use un valor predeterminado, 'no especificado' para cada parámetro, y pruebe contra eso antes de aplicar los valores de los parámetros al objeto en ProcessRecord()? Esto podría ser un poco difícil de manejar para productos grandes con muchos tipos de parámetros. –

+2

En v2.0 de powershell, se agregó una nueva propiedad: this.MyInvocation.BoundParameters donde "this" es PSCmdlet.Esta es una tabla hash de pares clave/valor de los nombres y valores de los parámetros que estaban vinculados al cmdlet. Si su enumeración fue especificada, estará en este diccionario. Si incumplió, no estará allí. No estoy al tanto de nada que no sea hacking de cadenas que hará lo mismo en v1.0 – x0n

+0

x0n, gracias, vi esa propiedad 2.0. Lamentablemente, necesito codificar contra 1.0 por ahora. Creo que la respuesta de Keith a continuación, utilizando un contenedor de nullable, es exactamente lo que estoy buscando. –

1

Sé que este hilo es un poco viejo, pero la mejor manera de hacer esto es declarar el parámetro utilizando el tipo SwitchParameter. Entonces sus usuarios no tienen que pasar -IsEnabled, simplemente agregarían algo así como -Enabled como parámetro.

Luego, prueba la propiedad .IsPresent de su parámetro para ver si la persona que llama agregó -Activado a la llamada al cmdlet.

+0

@Darren: eso definitivamente funciona para bool params, pero estaba buscando una solución para params no bool opcionales. El tipo de nullable parece funcionar bien. Por supuesto, PS v2 ahora tiene un diccionario de params disponible en el cmdlet, por lo que probablemente sea el camino a seguir. Gracias. –

0
bool wasSpecified = MyInvocation.BoundParameters.ContainsKey("IsEnabled"); 
+0

Tenga en cuenta que esto no funciona correctamente con los parámetros posicionales. No se encuentran por Nombre en BoundParameters, pero están especificados y tienen un valor. –

Cuestiones relacionadas