2008-12-17 16 views
7

Imagine este caso en el que tengo un objeto que necesito verificar una propiedad. Sin embargo, el objeto actualmente puede tener un valor nulo.Estructura de IF encadenada

¿Cómo puedo verificar estas dos condiciones en una sola condición "si"?

Actualmente, tengo que hacer algo como esto:

if (myObject != null) 
{ 
    if (myObject.Id != pId) 
    { 
     myObject.Id = pId; 
     myObject.Order = pOrder; 
    } 
} 

me gustaría algo como esto:

if (myObject != null && myObject.Id != pId) 

Deseo evaluar la segunda condición sólo si el primero era cierto.

Tal vez me falta algo, y por eso necesito su ayuda ;-)

+0

¿Por qué 'if (myObject! = Null && myObject.Id! = PId)' arroja una excepción? ¡Creo que es exactamente lo que quieres! –

+0

@Carlos Ahora está arreglado. –

Respuesta

43
if(myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 

&& es una prueba de la lógica de cortocircuito - que sólo evalúa la mano del lado derecho si la izquierda lado de la mano es cierto. Contraste con "un & b", que siempre se evalúa ambos lados (y hace un bit a bit "y")

+0

Ok, pero no quiero arrojar ninguna excepción. Solo quería evaluar la segunda condición si la primera era verdadera. –

+0

Actualizar la página ;-p –

+0

Nelson, el código hace exactamente eso. Si myObject es nulo, la parte correcta de if nunca será evaluada. –

5
if (myObject != null && myObject.Id != pId) 
{ 
//bla 
} 

esto es seguro porque operador & & se evalúa con pereza, lo que significa que si el LHS es falsa, el RHS Nunca se evalúa

+0

Puedo decir que ya aprendí algo hoy. Gracias. –

1
if (myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
4

Este código primero comprueba si myObject no es nulo, en el caso de que es cierto que se compruebe la siguiente condición, en el caso de que no es cierto que no se compruebe la siguiente condición y no ejecuta el código.

if (myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
3

Tienes muchas buenas respuestas sobre cómo hacerlo. Solo quiero poner una advertencia sobre cómo no hacerlo. No envuelva la prueba única para id = pid en un bloque try-catch. Es un desperdicio y supondría la introducción de una verificación de excepción para atrapar una condición no excepcional. Es una mala idea que ni siquiera voy a ilustrarlo con un ejemplo.

+0

Sí, tienes razón. Yo no haría eso, de todos modos. Primero verificaría el valor nulo en myObject. –

10

Cabe destacar que la evaluación en cortocircuito de la & & en el caso de() está absolutamente garantizada por los estándares del lenguaje (C, C++, Java y C#). Ha sido así desde la primera edición de K & R's "C Programming Language".

No es algo de lo que tenga que preocuparse "¿Funciona mi compilador esto?". Si definitivamente hace.

+0

Gracias, no sabía esta cosa de la evaluación en cortocircuito. Parece un poco cojo ahora, pero es la verdad. –

+0

¡Es algo * que mucha gente desconoce! Y muchos que se topan con eso, piensan que es una peculiaridad del compilador. –

1
if(!(myObject == null || myObject.Id == pId)) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
1

Creo que en VB.net puede utilizar la palabra clave andAlso como alternativa a este comportamiento. Así que algo como ...

if(myObject != null andAlso myObject.Id != pId) 
    { 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
    } 

hace exactamente lo mismo que yo creo pero está allí como una alternativa!

Editar: cambió C# a VB.neto por encima de

+0

C# no tiene la palabra clave andAlso.Aunque, VB lo tiene, y eso fue lo que recordé, desde que comencé .NET con VB. Pero la respuesta es && operador. –

+0

¡Vaya! Disculpas por eso. Publicación editada para reflejar ese hecho – chillysapien

1

Dado que creo que puede ser útil para otros que miran esta pregunta en el futuro. Como se indicó, el uso de & & proporciona la funcionalidad que desea. Pero, también debe tenerse en cuenta, la funcionalidad que tenía miedo, que ambas partes serían evaluadas independientemente del resultado de la primera evaluación se puede obtener utilizando & en lugar de & &. Entonces:

//DO NOT USE THIS CODE 
//this will throw an exception if myObject is null 
//because myOject.Id != pId will still be evaluated 
if(myObject != null & myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 

De nuevo, para este ejemplo, NO QUIERE este código. Simplemente quería añadirlo a la conversación, porque puede haber casos (aunque nunca he encontrado uno), donde ésta es la funcionalidad que desee, por ejemplo:

//always run both methods 
if(MethodA() & MethodB()) 
{ 
    //do stuff only when both methods return true 
} 
+0

Buena contribución. Gracias. –

1

Puede utilizar & para evaluar dos condiciones, pero si quiere probar el segundo solo si el primer elemento es verdadero, puede usar & &.

En portugués llamamos esto: "AND com curto circuito".

if (myObject != null && myObject.Id != pId) 

si myObject es falso que no se puede probar myObject.Id porque myObject es nula y no se puede acceder a una propiedad de un objeto nulo.

:::::::::::::::::::::::

aba & & b

cierto cierto cierto

verdadero falso falso

falso verdadero falso

false false false

:::::::::::::::::::::::