2009-08-20 14 views
13

¿Cuál es una mejor práctica? (Estoy de codificación en .Net si eso hace la diferencia)Mejores prácticas en IF/ELSE Orden de declaración

IF condition = true THEN 
    ...true action--even if rare... 
ELSE 
    ...action 
END IF 

o

IF condition = [most common condition] THEN 
    ...most common action.... 
ELSE 
    ...least common action 
END IF 
+0

Su pregunta no tiene mucho sentido. No está claro lo que estás preguntando. ¿Podrías aclararlo por favor? –

+0

En la segunda instrucción, la condición else nunca se ejecutará –

+1

La segunda podría estar mejor redactada "Si condición = [condición más común] ENTONCES" en lugar de "verdadero o falso" - entiendo lo que está tratando de decir, pero esa es una manera confusa de expresarlo. – matthock

Respuesta

31

De acuerdo con Steve McConnell, autor de código completo, usted debe

"Put the case you normally expect to process first. This is in line with the general principle of putting code that results from a decision as close as possible to the decision...[putting the normal case after the if] puts the focus on reading the main flow rather than on wading through the exceptional cases, so the code is easier to read overall."

Code Complete , 2da Edición, páginas 356-357.

+1

Tiendo a estar de acuerdo, pero a veces, cuando puede haber anidado niveles de casos excepcionales, es difícil para identificar cuál es cuál después de que se hace el caso normal. a veces es bueno ver las excepciones una tras otra y si has logrado pasar al final sabes que lo que estás procesando es normal. –

+1

Ty W, así es como haces que el programa haga controles innecesarios la mayor parte del tiempo. – Breakthrough

+2

+1 para hacer referencia * Código completo *. – Imagist

7

Ir con la versión más legible para su caso específico, y por cierto, no se pueden comparar una expresión booleana a verdadero y falso. Utilice condition y Not condition (!condition en C#.)

if (condition == true) // bad 
if (condition) // better 
+0

Simplemente curioso, pero ¿por qué es (condición == verdadero) considerado malo? ¿Demasiado prolijo? – Jeff

+4

Primero, desordena el código. Mientras menos escriba, menos necesitará leer y comprender. Además, existe la posibilidad de que pierda un signo igual y se convierte en 'if (condición = verdadero)' que no es lo que quiere. (Afortunadamente, el compilador C# emitirá una advertencia, pero ¿por qué no lo previene desde el principio?) –

+3

mi práctica personal es hacer si (condición) para una evaluación verdadera, y si (condición == falsa) para una evaluación falsa. Me parece demasiado fácil pasar por alto si (! Condición), además, personalmente, creo que se lee mejor "si no la condición" frente a "si la condición es falsa" – Matt

1

Utilice el que hace que el código sea más fácil de leer. Esta suele ser la segunda de tus opciones.

Editar

En muchos casos, depende de lo que estamos tratando de lograr, por ejemplo, si desea comprobar que una conexión se inició correctamente:

Connect() 
if connected then 
    SendString("Hello!") 
else 
    FlagConnectionFailed() 
endif 

Mientras Si se desea capturar un error:

' Just about to send something 
if not connected then 
    FlagConnectionLost() 
    return 
endif 
SendString("Still connected!") 

Pero es posible que incluso quieren:

Disconnect() 
if not connected then 
    return "Complete" 
else 
    FlagConnectionDisconnectFailure() 
endif 

(no soy un programador de VB, por lo que la sintaxis anterior se compone en gran parte!)

3

En primer lugar, no se debe comparar con los valores booleanos, esto es, hacer

if condition then 

en lugar de

if condition = true then 

Sobre su pregunta, que depende de los nombres de las variables naturales, la OMI .

Por ejemplo, si va a crear un cliente que necesita para comprobar si está conectado (el caso más común)

if connected then 
    //Proceed 
else 
    //Throw error 
end if 

O, si va a crear un programa diferente, donde se tiene una variable, digamos , recuperará y se desea saber si el contenido se ha recuperado

if not retrieved then 
    //Error 
end if 

no haga

if retrieved then 
else 
    //Error 
end if 
1

Como otros han dicho, la legibilidad es generalmente más importante. Sin embargo, la legibilidad significa diferentes cosas para diferentes personas.

Para mí, que por lo general significa que la organización de la instrucción if para que el más corto acción (en términos de líneas de código) es lo primero, por lo que si la afirmación es cerca de la parte inferior de la ventana estoy más probabilidades de ver el "Else" en la pantalla.

Para otros, colocar un "No" en la condición realmente puede arrojarlos, por lo que preferirán enumerarlo para que la condición If siempre sea lo más positiva posible.

2

En general, siempre pongo la cláusula verdadera primero. Algo como esto, para mí, ofusca significado:

If not something Then 
    'do something 1 
Else 
    'do something 2 
End If 

Esto se traduce en una doble negación, mucho mejor para escribir así:

If something Then 
    'do something 2 
Else 
    'do something 1 
End If 

Creo que esta recomendación viene de código completo. Un gran libro vale la pena leer

http://www.cc2e.com/

Si usted va a tener más de una persona, entonces puede ser mejor considerar una declaración de caso.

1

La mejor práctica es la segunda opción - la acción más común primero.

Hace que sea más fácil leer el código ya que no está distraído por el código para el caso menos usado/excepcional.

3

En el ensamblaje final/código de máquina, hace la diferencia. La declaración que es más probable que se ejecute se hace en la ruta sin la rama. De esta forma, la tubería no se rompe y se pierden valiosos ciclos.

No tengo idea si el compilador deja intacto su orden de instrucciones if then y de esta manera fuerza al ensamblado a tomar esta ruta optimizada.

He leído que visual studio 2008 (cuando se anunció) tendría una funcionalidad de optimización donde el compilador agrega medidas en las ramas y luego durante el tiempo de ejecución mide la frecuencia con la que se toma una ruta certificada. Luego, en las recompilaciones posteriores, se prefiere la ruta de código más óptima.

no tengo idea de si esta característica nunca llegó más allá del 'diseño/fase académica'

+1

@reinier Esta optimización en tiempo de compilación se implementó en el compilador de HotSpot para Java. Creo que esto también se implementó en .NET porque Microsoft está bajo mucha presión para mantenerse al día con los Jones. – Imagist

+1

La optimización de la que estoy hablando se trata realmente del nivel de código de máquina (para el compilador de C). Así que no hay optimizaciones de bytecode para .net y java como los programas. – Toad

1

Si el caso más común no es el más simple de expresar, es posible que tenga una oportunidad para re-factorización

Una utilidad re-factoring que he encontrado:

if (a.getFoo() == 1 && a.getBar() == 2) 

se puede volver a factorizar a

if (a.isFooBar()) 

En casos vienen algo desagradable como este,

if (!(fooSet.contains(a.getValidFoo()))) 

podría ser

if (a.hasInvalidFoo(fooSet)) 

Esto puede hacer que la opción 1 opción 2 también sea mediante la simplificación de la evaluación de la condición más común.

2

Ya ha recibido algunas buenas respuestas. Voy a abordar la pregunta desde un ángulo diferente.

Primero, en lo que respecta al rendimiento, puede no importar tanto como piense en las CPU modernas. Esto se debe a que usan una función llamada predicción de bifurcación en la cual la CPU intenta predecir la dirección más probable que tomará el código. Por supuesto, todavía estoy de acuerdo en que debes colocar la rama más probable en la parte superior si el rendimiento es tu principal preocupación.

En segundo lugar, prefiero la legibilidad a las mejoras de rendimiento triviales. En la mayoría de los casos, el beneficio de la legibilidad supera a los de rendimiento.

En tercer lugar, use guard clauses cuando sea posible. Hace que el código sea más legible.