2009-04-27 13 views
16

Al parecer, esto solía ser una forma en VB6 y VBA a cortocircuitos y ejecutar el primer caso cierto:Select Case verdadera

Select Case True 
End Select 

¿Es esta todavía en uso (VB.NET)?

+0

Utilice los operadores de cortocircuito 'AndAlso' y' OrElse' en VB.NET, en lugar de este hack 'Select Case'. –

Respuesta

26

Esta sintaxis se utiliza a menudo en lugar de un If...ElseIf declaración. Algunas personas les resulta un poco más fácil de leer. Por ejemplo:

Select Case True 
    Case testVariable < 0 
     Console.Write("You must supply a positive value.") 
    Case testVariable > 10 
     Console.Write("Please enter a number from 0-10.") 
    Case True 
     Call DoWork(testVariable) 
End Select 

La respuesta es que sí, esto todavía funciona en VB.NET. Solo tenga cuidado cuando lo use, porque no es una "construcción de programación estándar" y puede no ser familiar para las personas que tienen que mantener su código en el futuro.

+0

Sí, ese es el indicado. ¡Gracias! –

3

¿Te refieres a algo como esto?

Select Case True 
    Case 1 = 0 
     Console.Write("1") 
    Case 1 = 1 
     Console.Write("2") 
    Case 2 = 2 
     Console.Write("3") 
End Select 

En el que, el programa escribiría 2 ... si eso es lo que estás pidiendo, entonces sí, es todavía alrededor en VB.NET

12

no estoy seguro de cómo esta construcción ofrece alguna ventaja sobre los siguientes:

If testVariable < 0 Then 
    Console.Write("You must supply a positive value.") 
ElseIf testVariable > 10 Then 
    Console.Write("Please enter a number less than 10.") 
Else 
    Call DoWork(testVariable) 
End If 

La estructura anterior es un cortocircuito, y no tienen que tratar de llegar a lo que hace, ya que es una construcción estándar.

+0

No es así, pero muchos programadores de VB se equivocan al lado del formato más puramente legible, y podría argumentarse que la pregunta describe exactamente esa condición. Sin embargo, la mayor variedad de desarrolladores de C-esque que existen definitivamente están en tu campamento. Ver también @RolandTumble. – Hardryv

9

Otros ya han respondido esa pregunta real, pero solo quiero decir que utilizo esta construcción con bastante frecuencia. Creo que es a menudo la forma más legible de probar simultáneamente dos condiciones booleanas:

Dim A As Boolean 
Dim B As Boolean 
' 
'do stuff to set values of A and B 
' 
Select Case True 
    Case A And B 
    'something 
    Case A And Not B 
    'something else 
    Case Not A And B 
    'you get the picture 
    Case Else 
    '... 
End Select 

Tengo que reconocer que parte de la razón por la que resulta fácil de leer es que hago uso de ella, y que sí recuerdo tener que analizar es el La primera vez que lo vi, pero una vez analizado con éxito, mi reacción fue "¡Eso es brillante!"

9

Hay mucha confusión en este tema, pero para responder a la pregunta de OP: Sí, la evaluación lógica es la misma en VB.Net que en VB6 como en VBA. http://support.microsoft.com/kb/817250

Para aprovechar la técnica de optimización Seleccionar caso, utiliza la sintaxis inherente Seleccionar Casos para evitar el uso de los Operadores Lógicos Y, O, Xor, etc. Son estos operadores que tienen una evaluación de Cortocircuito.

Considere este ejemplo:

Public Sub Example() 
    If A Or B Then 
     Beep 
    End If 
    Select Case True 
     Case A, B 
      Beep 
    End Select 
End Sub 

Private Function A() As Boolean 
Debug.Print "A Ran" 
    A = True 
End Function 

Private Function B() As Boolean 
Debug.Print "B Ran" 
    B = False 
End Function 

La versión Select Case sólo se ejecutará A. El bloque if se ejecutará tanto. Esto no es culpa de la declaración If, sino que es culpa del operador Y. Si lo prefiere, puede estructurar el enunciado If en cortocircuito como este:

Public Sub Example2() 
    If A Then 
    ElseIf B Then 
     Beep 
    End If 
End Sub 

Y B no se ejecutará. Todo es solo una cuestión de estilo.

Lo importante que debe saber es que lo que está evitando es que los operadores And/Or/Xor no sean los If-Blocks. Si le gusta la versión Select Case del If-Block mejor ... Más poder para usted :)

+3

Tenga en cuenta que puede usar OrElse para cortocircuitar y ejecutar solamente A. – Jack

3

Select Case es a powerful operator by itself. Pero aunque todavía se admite Select Case True, es mejor evitarlo para la perspectiva de mantenimiento.Siempre tienes que justificar la necesidad. Si es necesario, incluso puede usar DoEvents y GoTo. Para la respuesta aceptada, podría escribirse así:

Select Case testVariable 
    Case Is < 0 : Console.Write("You must supply a non-negative value.") 
    Case Is > 10 : Console.Write("Please enter a number from 0-10.") 
    Case Else : Call DoWork(testVariable) 
End Select 
+0

Nitpicky para señalar, pero "0" no es un "valor positivo". ^^ – Hardryv

+1

@Hardryv: ¿Es mejor ahora? :) – Neolisk

+0

de hecho lo es;) – Hardryv

2

Puede definir el operador Igual en cualquier tipo de envoltura. Luego puede usar el tipo de Contenedor en Seleccionar Caso.

Contenedor de muestras.

Imports System.Runtime.InteropServices 
<DebuggerStepThrough()> Friend Module Util 
    Public Function _Is(v As Object) As IsWrapper 
     Return New IsWrapper With {.Obj = v} 
    End Function 
    Public Structure IsWrapper 
    Public Obj As Object 
    Public Shared Operator =(ByVal a As IsWrapper, ByVal b As Object) As Boolean 
     Return a.Obj Is b 
    End Operator 
    Public Shared Operator <>(ByVal a As IsWrapper, ByVal b As Object) As Boolean 
     Return a.Obj IsNot b 
    End Operator 
    End Structure 
End Module 

Ahora puede utilizar _is (AnyObject):

Private Sub RbClass_CheckedChanged(sender As System.Object, e As System.EventArgs) 
    If DirectCast(sender, RadioButton).Checked = False Then Return 
    Select Case _Is(sender) 
     Case RbClass : Rb = 0 
     Case RbTablePredicate : Rb = 1 
     Case RbTableRowFilter : Rb = 2 
    End Select 
    QueryCtl1_QueryChanged(Nothing, Nothing) 
End Sub 

Public Sub Predicate(ByVal PredicateType As Type, ByVal Op As Operadores, ByVal Obj As Object, ByVal CompareOptions As CompareOptions, ByVal Fnc As [Delegate]) 
    Dim pred As [Delegate] = Nothing 
    Select Case _Is(PredicateType) 
     Case GetType(Boolean) 
      pred = New Predicate(Of Boolean)(Function(v) v) 
     Case GetType(String) 
      pred = StrPredicate(Op, Obj, CompareOptions) 
     Case Else 'Utilizar Generics 
      pred = GenericHelper.Builder(PredicateType).Predicate(Op, Obj) 
    End Select 
    Predicate(pred, Fnc) 
End Sub 

sobre el rendimiento. Release Code está optimizado. Wrapper no tiene ninguna penalización de rendimiento.

+0

nice one x77. ^^ – Hardryv

1

Después de leer este hilo, parece que el argumento principal para Select Case True es la legibilidad. ¿Es suficiente? Cuando vi por primera vez el constructo utilizado así en VB.NET, tuve que leerlo un par de veces para asegurarme de que tenía la esencia, pero aún pensaba en la misma línea que RolandTumble, above. Entonces, incluso la legibilidad tiene un pequeño costo. Todo el mundo sabe lo que es una declaración If...ElseIf...End If y por qué está allí. El cortocircuito puede ser ayudado usando AndAlso o OrElse, y la complejidad es puramente del código y del codificador involucrados.

Incluso las declaraciones If se pueden optimizar. ¿De qué sirve preguntar lo obvio? (Ya sea value = True). Una vez me preguntaron qué hizo la siguiente por un codificador trabajar con nosotros ...

Dim isVisible As Boolean 
.... 
If isVisible Then 
    .... 
End If 

El uso de la estructura Select Case True también se siente como usted se está moviendo el foco o del énfasis de la comparación de la línea real y Select Case en las declaraciones Case, por extraño que suene.

1

Otra razón para usar el constructo SELECCIONAR CASO VERDADERO es cuando las declaraciones de su caso se evalúan a un valor booleano. El SELECT CASE necesita que todos los casos se evalúen con el mismo tipo de datos que el control. Si está buscando un tipo de datos de cadena, entonces todas las declaraciones de casos también deben ser cadenas.

SELECT CASE [string] 
CASE "String 1", "String 2" 
    [do a thing] 
CASE "String 3" 
    [do another thing] 
END SELECT 

Sin embargo, si usted está comparando secuencias parciales utilizando el operador LIKE entonces su tipo de datos booleano caso se convierte en el cual no coincidirá con el control de la cadena. El siguiente código no funcionará:

SELECT CASE [string] 
CASE LIKE "*1", "*2" 
    [do a thing] 
CASE LIKE "*3" 
    [do another thing] 
END SELECT 

Para utilizar comodines (y por lo tanto tienen resultados de los casos booleanas) que tiene que tener un valor de control booleano, por tanto, la estructura tiene que ser:

SELECT CASE TRUE 
CASE [string] LIKE "*1", "*2" 
    [do a thing] 
CASE [string] LIKE "*3" 
    [do another thing] 
END SELECT 

supongo que se podría utilizar IF ... ELSEIF

IF [string] LIKE "*1" AND [string] LIKE "*2" THEN 
    [do a thing] 
ELSEIF [string] LIKE "*3" 
    [do another thing] 
END IF 

Personalmente, creemos que la SELECT CASE es más fácil de usar y leer cuando hay más de tres opciones. Uso IF ... ELSE y IF ... ELSEIF cuando tengo que evaluar dos o tres opciones diferentes (>, =, <) o si estoy probando un valor para un rango específico de entradas "válidas". Si, en cambio, la entrada tiene más variedad y necesito determinar cuál de las diez posibilidades ha sucedido, SELECT CASE es una construcción mucho más fácil de usar ya que elimina la necesidad de múltiples instrucciones OR.