vb.net - que - operador andalso
O frente a OrElse (6)
(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 ...)
¿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
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.
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 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.
OrElse evalúa la primera expresión y luego si es verdadera, procederá a la declaración mientras OR evalúa dos expresiones antes de proceder a su declaración.
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.
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.