O frente a OrElse

¿Cuál es la diferencia entre o y OrElse ?

if temp is dbnull.value or temp = 0 

produce el error:

El operador ‘=’ no está definido para el tipo ‘DBNull’ y escribe ‘Entero’.

mientras que este funciona como un encanto !?

 if temp is dbnull.value OrElse temp = 0 

OrElse es un operador de cortocircuito , Or no lo es.

Según la definición del operador booleano ‘o’, si el primer término es verdadero, entonces el todo es definitivamente cierto, por lo que no es necesario evaluar el segundo término.

OrElse sabe, por lo que no prueba y evalúa temp = 0 una vez que se establece que la temp Is DBNull.Value

Or no lo sabe, y siempre intentará evaluar ambos términos. Cuando temp Is DBNull.Value , no se puede comparar con cero, por lo que se cae.

Deberías usar … bueno, cualquiera que tenga sentido.

Este es el mismo comportamiento que con C #, donde todos usan el Coditional Or (||) y el Conditional And (&&), donde también tiene el normal O (|) y el normal And (&). Entonces, comparar C # con VB.Net es:

| => O

|| => OrElse

& => Y

&& => Y también

Los operadores booleanos condicionales son muy útiles para evitar construcciones anidadas. Pero a veces los operadores booleanos normales son necesarios para asegurar el acceso a ambas rutas de código.

OrElse está cortocircuitado , esto significa que solo se probará un lado de la expresión si el primer lado es una coincidencia.

Al igual que AndAlso solo probará un lado de la expresión si la primera mitad falla.

(Miré otras respuestas y me di cuenta de que estaba terriblemente equivocado)

El operador OrElse “realiza el cortocircuito de la disyunción lógica en dos expresiones”, es decir: si el operando izquierdo es verdadero y entonces se garantiza que la expresión completa es verdadera, el operando correcto ni siquiera se evaluará (esto es útil en casos como:

 string a; //... if (a is null) or (a = "Hi") //... 

para evitar una tirada de NullReferenceException con el operando de la derecha.

Estoy sinceramente asombrado de que esto ( evaluación diferida ) no sea el comportamiento predeterminado de andy como está en C / C ++ y C # (y en muchos otros idiomas …)

La respuesta de Bert no es muy precisa. El ‘|’ o ‘&’ es operador lógico, en C #, siempre lo trata como operador de bit, por favor vea el siguiente código como ejemplo

  static void Main() { object a = null; int b = 3; if (a == null | a.ToString() == "sdffd") { Console.WriteLine("dddd"); } Console.WriteLine(b | b); Console.Read(); } 

Lo siguiente es IL

  .method private hidebysig static void Main() cil managed { .entrypoint // Code size 62 (0x3e) .maxstack 3 .locals init ([0] object a, [1] int32 b, [2] bool CS$4$0000) IL_0000: nop IL_0001: ldnull IL_0002: stloc.0 IL_0003: ldc.i4.3 IL_0004: stloc.1 IL_0005: ldloc.0 IL_0006: ldnull IL_0007: ceq IL_0009: ldloc.0 IL_000a: callvirt instance string [mscorlib]System.Object::ToString() IL_000f: ldstr "sdffd" IL_0014: call bool [mscorlib]System.String::op_Equality(string, string) IL_0019: or IL_001a: ldc.i4.0 IL_001b: ceq IL_001d: stloc.2 IL_001e: ldloc.2 IL_001f: brtrue.s IL_002e IL_0021: nop IL_0022: ldstr "dddd" IL_0027: call void [mscorlib]System.Console::WriteLine(string) IL_002c: nop IL_002d: nop IL_002e: ldloc.1 IL_002f: ldloc.1 IL_0030: or IL_0031: call void [mscorlib]System.Console::WriteLine(int32) IL_0036: nop IL_0037: call int32 [mscorlib]System.Console::Read() IL_003c: pop IL_003d: ret } // end of method Program::Main 

cuando usas || para probar “a == null” y “a.ToString () ==” sdffd “, la IL será

  .method private hidebysig static void Main() cil managed { .entrypoint // Code size 63 (0x3f) .maxstack 2 .locals init ([0] object a, [1] int32 b, [2] bool CS$4$0000) IL_0000: nop IL_0001: ldnull IL_0002: stloc.0 IL_0003: ldc.i4.3 IL_0004: stloc.1 IL_0005: ldloc.0 IL_0006: brfalse.s IL_001d IL_0008: ldloc.0 IL_0009: callvirt instance string [mscorlib]System.Object::ToString() IL_000e: ldstr "sdffd" IL_0013: call bool [mscorlib]System.String::op_Equality(string, string) IL_0018: ldc.i4.0 IL_0019: ceq IL_001b: br.s IL_001e IL_001d: ldc.i4.0 IL_001e: stloc.2 IL_001f: ldloc.2 IL_0020: brtrue.s IL_002f IL_0022: nop IL_0023: ldstr "dddd" IL_0028: call void [mscorlib]System.Console::WriteLine(string) IL_002d: nop IL_002e: nop IL_002f: ldloc.1 IL_0030: ldloc.1 IL_0031: or IL_0032: call void [mscorlib]System.Console::WriteLine(int32) IL_0037: nop IL_0038: call int32 [mscorlib]System.Console::Read() IL_003d: pop IL_003e: ret } // end of method Program::Main 

Ahora puedes ver la diferencia, por favor no pienses que ‘|’ o ‘y’ como operador condicional, es solo un operador lógico, no creo que sea necesario usarlo para juzgar las condiciones

OrElse evalúa la primera expresión y luego si es verdadera, procederá a la statement mientras OR evalúa dos expresiones antes de proceder a su statement.

Ejemplo:

 Textbox1.Text= 4 Textbox2.Text= "" 

Usando OrElse

  If TextBox1.Text > 2 OrElse TextBox2.Text > 3 Then MsgBox("True") End If 

El resultado es: VERDADERO


Usando OR

  If TextBox1.Text > 2 Or TextBox2.Text > 3 Then MsgBox("True") End If 

El resultado es: Error no puede convertir cadena a doble.