Pregunta

He visto algo como lo siguiente un par de veces ... y lo odio. ¿Es esto básicamente "engañar" al lenguaje? O ... ¿consideraría que esto está 'bien' porque el IsNullOrEmpty se evalúa primero, todo el tiempo?

(Podríamos argumentar si una cadena debe ser NULL o no cuando sale de una función, pero esa no es realmente la cuestión).

string someString;
someString = MagicFunction();

if (!string.IsNullOrEmpty(someString) && someString.Length > 3)
{
    // normal string, do whatever
}
else
{
   // On a NULL string, it drops to here, because first evaluation of IsNullOrEmpty fails
   // However, the Length function, if used by itself, would throw an exception.
}

EDITAR: Gracias de nuevo a todos por recordarme este lenguaje fundamental. Si bien sabía "por qué" funcionó, no puedo creer que no supiera / recuerde el nombre del concepto.

(En caso de que alguien quiera algún fondo ... Encontré esto al solucionar problemas de excepciones generadas por cadenas NULL y .Length > x excepciones ... en diferentes lugares del código. Entonces, cuando vi el código anterior, además a todo lo demás, mi frustración se hizo cargo de allí.)

¿Fue útil?

Solución

Está aprovechando una función de lenguaje conocida como cortocircuito. Esto no es engañar al lenguaje, sino que de hecho usa una función exactamente como fue diseñada para ser utilizada.

Otros consejos

Si está preguntando si está bien depender del " cortocircuito " operadores relacionales & amp; & amp; y || , entonces sí, eso está muy bien.

No hay nada de malo en esto, ya que solo quiere asegurarse de que no obtendrá una excepción de puntero nulo.

Creo que es razonable hacerlo.

Con Extensiones puede hacerlo más limpio, pero el concepto básico aún sería válido.

Este código es totalmente válido, pero me gusta usar el Operador de fusión nula para evitar verificaciones de tipo nulo.

string someString = MagicFunction() ?? string.Empty;
if (someString.Length > 3)
{
    // normal string, do whatever
}
else
{
   // NULL strings will be converted to Length = 0 and will end up here.
}

No hay nada de malo en esto.

if (las condiciones se evalúan de izquierda a derecha, por lo que está perfectamente bien apilarlas así.

Este es un código válido, en mi opinión (aunque declarar una variable y asignarla en la siguiente línea es bastante molesto), pero probablemente deberías darte cuenta de que puedes ingresar el bloque else también en la condición donde la longitud del cadena es < 3.

Eso me parece un uso perfectamente razonable del cortocircuito lógico; en todo caso, es engañar a con el lenguaje. Recientemente he venido de VB6 que nunca cortocircuito, y eso realmente me molestó >.

Un problema a tener en cuenta es que es posible que deba probar Null nuevamente en esa cláusula más, ya que, como está escrito, está terminando allí con cadenas Null y cadenas de longitud menor que tres .

Esto es perfectamente válido y no hay nada de malo en usarlo de esa manera. Si sigue un comportamiento documentado para el idioma, entonces todo está bien. En C #, la sintaxis que está utilizando son los operadores lógicos condicionales y su bahioour docementado se puede encontrar en MSDN

Para mí es lo mismo que cuando no usas paréntesis cuando haces multiplicación y suma en la misma declaración porque el lenguaje documenta que las operaciones de multiplicación se llevarán a cabo primero.

Confiar en el cortocircuito es lo correcto. hacer en la mayoría de los casos. Conduce a un código terser con menos partes móviles. Lo que generalmente significa más fácil de mantener. Esto es especialmente cierto en C y C ++.

Consideraría seriamente contratar a alguien que no esté familiarizado con (y no sepa cómo usar) las operaciones de cortocircuito.

Me parece bien :) Solo te estás asegurando de no acceder a una variable NULL. En realidad, siempre hago esa verificación antes de realizar cualquier operación en mi variable (también, al indexar colecciones, etc.): es una práctica más segura, mejor, eso es todo ...

Tiene sentido porque C # por defecto cortocircuita las condiciones, así que creo que está bien usar eso para su ventaja. En VB puede haber algunos problemas si el desarrollador usa AND en lugar de ANDALSO.

No creo que sea diferente a algo como esto:

INT* pNumber = GetAddressOfNumber();

if ((pNUmber != NULL) && (*pNumber > 0))
{
  // valid number, do whatever
}
else
{
  // On a null pointer, it drops to here, because (pNumber != NULL) fails
  // However, (*pNumber > 0), if used by itself, would throw and exception when dereferencing NULL
}

Simplemente está aprovechando una característica del idioma. Creo que este tipo de lenguaje ha sido de uso común, ya que C comenzó a ejecutar expresiones booleanas de esta manera (o cualquier lenguaje que lo hiciera primero).

Si se tratara de un código en c que compiló en ensamblado, no solo está provocando un cortocircuito en el comportamiento correcto, es más rápido . En lenguaje de máquina, las partes de la declaración if se evalúan una tras otra. No cortocircuito es más lento.

Escribir código cuesta mucho $ a una empresa. ¡Pero mantenerlo cuesta más!

Entonces, estoy de acuerdo con su punto: lo más probable es que esta línea de código no sea entendida inmediatamente por el tipo que tendrá que leerla y corregirla en 2 años.

Por supuesto, se le pedirá que corrija un error crítico de producción. Buscará aquí y allá y puede que no note esto.

Siempre debemos codificar para el próximo tipo y él puede ser menos inteligente que nosotros. Para mí, esto es lo único para recordar.

Y esto implica que usamos características de lenguaje evidentes y evitamos las demás.

Todo lo mejor, Sylvain.

Un poco fuera de tema, pero si tienes el mismo ejemplo en vb.net así

dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) and someString.Length > 3 then
    ' normal string, do whatever
else
    ' do someting else
end if

esto funcionaría en una cadena nula (nada) pero en VB.Net lo codifica de la siguiente manera, haga lo mismo en C #

dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) andalso someString.Length > 3 then
    ' normal string, do whatever
else
    ' do someting else
end if

agregar el andalso también hace que se comporte de la misma manera, también se lee mejor. Como alguien que desarrolla vb y c ', el segundo vb muestra que el inicio de sesión es ligeramente diferente y, por lo tanto, es más fácil explicarle a alguien que hay una diferencia, etc.

Drux

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top