Antworten:
OrElseist ein Kurzschlussbetreiber , Ornicht.
Nach der Definition des booleschen Operators 'oder' ist das Ganze definitiv wahr, wenn der erste Term True ist - wir müssen also den zweiten Term nicht bewerten.
OrElseweiß das, also versuche nicht zu bewerten, temp = 0sobald es das festgestellt hattemp Is DBNull.Value
Orweiß das nicht und wird immer versuchen, beide Begriffe zu bewerten. Wenn temp Is DBNull.Valuees nicht mit Null verglichen werden kann, fällt es um.
Sie sollten verwenden ... nun, je nachdem, was sinnvoll ist.
Dies ist das gleiche Verhalten wie bei C #, wo jeder das Coditional Or (||) und das Conditional And (&&) verwendet, wobei Sie auch das normale Or (|) und das normale And (&) haben. Der Vergleich von C # mit VB.Net lautet also:
| => Or. En
|| => OrElse
& => Und
&& => AndAlso
Die bedingten booleschen Operatoren sind sehr nützlich, um verschachtelte if-Konstruktionen zu verhindern. Manchmal werden jedoch die normalen booleschen Operatoren benötigt, um sicherzustellen, dass beide Codepfade getroffen werden.
|und &sind bitweise Operatoren in C #, überhaupt keine booleschen Operationen.
OrElse ist kurzgeschlossen . Dies bedeutet, dass nur eine Seite des Ausdrucks getestet wird, wenn die erste Seite übereinstimmt.
Genau wie AndAlso wird nur eine Seite des Ausdrucks getestet, wenn die erste Hälfte fehlschlägt.
(Ich habe mir andere Antworten angesehen und festgestellt, dass ich mich schrecklich geirrt habe.)
Der OrElse-Operator "führt eine logische Kurzschluss-Disjunktion für zwei Ausdrücke durch", dh: Wenn der linke Operand wahr ist und somit garantiert wird, dass der gesamte Ausdruck wahr ist, wird der rechte Operand nicht einmal ausgewertet (dies ist nützlich in Fälle wie:
string a;
//...
if (a is null) or (a = "Hi") //...
um einen NullReferenceException-Wurf durch den rechten Operanden zu vermeiden.
Ich bin aufrichtig erstaunt, dass dies ( verzögerte Auswertung ) nicht das Standardverhalten von orund andwie in C / C ++ und C # (und vielen anderen Sprachen ...) ist.
OrElse wertet den ersten Ausdruck aus. Wenn er wahr ist, wird mit der Anweisung fortgefahren, während OR zwei Ausdrücke auswertet, bevor mit der Anweisung fortgefahren wird.
Beispiel:
Textbox1.Text= 4
Textbox2.Text= ""
Verwenden von OrElse
If TextBox1.Text > 2 OrElse TextBox2.Text > 3 Then
MsgBox("True")
End If
Ergebnis ist: WAHR
Verwenden von OR
If TextBox1.Text > 2 Or TextBox2.Text > 3 Then
MsgBox("True")
End If
Ergebnis ist: Fehler kann String nicht in Double konvertieren.
Die Antwort von Bert ist nicht sehr genau. Das '|' oder '&' ist ein logischer Operator, in C # wird er immer als Bitoperator behandelt. Den folgenden Code finden Sie als Beispiel
static void Main()
{
object a = null;
int b = 3;
if (a == null | a.ToString() == "sdffd")
{
Console.WriteLine("dddd");
}
Console.WriteLine(b | b);
Console.Read();
}
Das Folgende ist 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
wenn Sie || verwenden Um "a == null" und "a.ToString () ==" sdffd "zu testen, wird die IL sein
.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
Jetzt können Sie den Unterschied sehen, denken Sie bitte nicht an das '|' oder 'und' als bedingter Operator, es ist nur ein logischer Operator, ich glaube nicht, dass es notwendig ist, ihn zur Beurteilung der Bedingung zu verwenden
The '|' or '&' is logical operator, in C #, it always treat as bit operator. Ich habe auch daran geglaubt, bis ich diese Referenz sah, msdn.microsoft.com/en-us/library/kxszd0kx.aspx
Sofern Ihre Codelogik nicht das von OrElse bereitgestellte Kurzschlussverhalten erfordert, würde ich den Operator Or verwenden, weil:
Der Grund, warum die Kompilierung im Beispiel fehlschlägt, ist die Reihenfolge der Operationen.
Der Ausdrucksparser versucht zuerst, "dbnull.value or temp" auszuwerten.
if temp is (dbnull.value or temp) = 0
Der Fehler ist hier, weil Sie kein bitweises ODER zwischen einer Ganzzahl (temp) und dbnull.value ausführen können.
OrElse behebt dies nicht, weil es kurzgeschlossen ist, sondern weil es in der Reihenfolge der Operationen niedriger ist. Daher werden zuerst "temp is dbnull.value" und "3 = 0" ausgewertet, anstatt dass der Parser versucht, dbNull und zu vergleichen temp.
Die Auswertung mit OrElse funktioniert also wie erwartet: (Temp = 3 annehmen)
if temp is dbnull.value OrElse temp = 0 then
if 3 is dbnull.value OrElse 3 = 0 then
if false OrElse 3=0 then
if false OrElse false then
if false then
Dies war tatsächlich eine Aufnahmeprüfung bei einem Softwareunternehmen, für das ich früher gearbeitet habe, und es war ein häufiges Problem, auf das ich in VB6 gestoßen bin. Es ist daher eine gute Idee, Ihre Unterausdrücke in Klammern zu setzen, wenn Sie boolesche Operatoren verwenden:
Dies hätte richtig kompiliert:
if (temp is dbnull.value) Or (temp = 0) then
Obwohl, wie alle bereits betont haben, OrElse und AndAlso in diesem Zusammenhang wirklich die richtigen Operatoren sind.