Enfatice la negación

13

Estaba escribiendo una declaración if con nombres de propiedad bastante largos y encontré este problema.

Digamos que tenemos una declaración if como esta:

if(_someViewModelNameThatIsLong.AnotherPropertyINeedToCheck == someValue &&
   !_someViewModelNameThatIsLong.ThisIsABooleanPropertyThatIsImportant)
{
    //Do something
}

La segunda propiedad es de tipo booleano y no tiene sentido tener el stetement como

if(boleanValue == true)

¿Hay una mejor manera de enfatizar la negación que poner el !frente? Para mí, parece que esto se puede supervisar fácilmente al leer el código y puede causar problemas de depuración.

Ivan Crojach Karačić
fuente
77
Extraiga la condición en un método con un nombre significativo.
Joachim Sauer
2
... o asigne el valor negado a una variable con un nombre significativo y úselo en la condición if.
scrwtp
+1 lo que dijo @JoachimSauer, si es posible, coloque ese método en el objeto que se está consultando. En este caso, la condición completa podría encapsularse con un método en_someViewModelNameThatIsLong
MattDavey
2
Una cosa general que hago a menudo es rodear la negación con un espacio a cada lado para que sea más visible. if( ! something)vsif(!something)
Svish
Si enfatizas la negación, ¿por qué no usarla ... && model.Prop == false)? Personalmente rara vez lo uso !, es demasiado fácil pasarlo por alto.

Respuestas:

22
if(_someViewModelNameThatIsLong.NeedsMeToDoSomething(someValue))
{
    //Do something
}

Y luego, en la vista del objeto modelo

public bool NeedsMeToDoSomething(string someValue)
{
    return AnotherPropertyINeedToCheck == someValue &&
        !ThisIsABooleanPropertyThatIsImportant;
}

(suponiendo que someValue es una cadena y el objeto modelo no la conoce)

¡Esto no solo enfatiza el! operador, pero generalmente lo hace más legible. Ahora, en el método de llamada, puedo ver una condición, que debería estar bien nombrada para describir la condición en el contexto del objeto de llamada. Y en el objeto modelo, puedo ver lo que eso significa en el contexto del objeto modelo.

pdr
fuente
1
+1, esta es una buena aplicación del principio experto en información .
MattDavey
1
Vale la pena señalar que someValuepuede ser un parámetro del NeedsMeToDoSomethingmétodo, según su situación.
MattDavey
@ MattDavey: Oh, buen punto.
pdr
@pdr Tal vez debería hacer una propiedad para ese modelo de vista con el mismo valor booleano y reutilizar esa bandera en más lugares. Estoy seguro de que lo encontrará a mano.
radu florescu
5

Póngalo solo si bloque antes de evaluar las condiciones menos importantes. No solo sería más fácil de leer sin el desorden de las otras condiciones, sino que también es la primera condición que leerá un programador. Combine esto con la idea ya mencionada por @scrwtp para asignar a una variable con un nombre significativo y obtendrá:

var isValid = !_someViewModelNameThatIsLong.ThisIsABooleanPropertyThatIsImportant;
if( isValid ) 
{
    if( _someViewModelNameThatIsLong.AnotherPropertyINeedToCheck == someValue ) 
    {
        //Do something
    }
}

Si está programando en un lenguaje de compilación, la mayoría de las veces estos bloques anidados si se combinan al final de todos modos, siempre que no inserte código entre el if externo y el if interno, por lo que no debería afectar el rendimiento en estos casos.

Neil
fuente
2

Si está utilizando C / C ++, entonces el preprocesador podría proporcionarle legibilidad.

#define NOT !

if(_someViewModelNameThatIsLong.AnotherPropertyINeedToCheck == someValue &&
    NOT _someViewModelNameThatIsLong.ThisIsABooleanPropertyThatIsImportant)
{
    //Do something
}
CWallach
fuente
o tal vez ... función no (x) {return! x; } // javascript
Alex
2
Operadores en C y C ++ Ya hay sinónimos estándar para varios operadores.
Joel
0

Solo extraeria

`!_someViewModelNameThatIsLong.ThisIsABooleanPropertyThatIsImportant`

En un método que devuelve esto. Si nombra este método NotThisIsABooleanPropertyThatIsImportant, debería estar bien.

mhr
fuente