Or versus OrElse

vb.net

vb.net Problem Overview


What's the difference between or and OrElse?

if temp is dbnull.value or temp = 0

produces the error: > Operator '=' is not defined for type 'DBNull' and type 'Integer'.

while this one works like a charm!?

if temp is dbnull.value OrElse temp = 0

vb.net Solutions


Solution 1 - vb.net

OrElse is a short-circuiting operator, Or is not.

By the definition of the boolean 'or' operator, if the first term is True then the whole is definitely true - so we don't need to evaluate the second term.

OrElse knows this, so doesn't try and evaluate temp = 0 once it's established that temp Is DBNull.Value

Or doesn't know this, and will always attempt to evaluate both terms. When temp Is DBNull.Value, it can't be compared to zero, so it falls over.

You should use... well, whichever one makes sense.

Solution 2 - vb.net

This is the same behaviour as with C#, where everyone uses the Coditional Or (||) and the Conditional And (&&), where you also have the normal Or (|) and normal And (&). So comparing C# to VB.Net is:

| => Or

|| => OrElse

& => And

&& => AndAlso

The condifitonal boolean operators are very usefull preventing nested if constructions. But sometimes the normal boolean operators are needed to ensure hitting both code paths.

Solution 3 - vb.net

OrElse is short circuited, this means that only one side of the expression will be tested if the first side is a match.

Just like AndAlso will only test one side of the expression if the first half is a fail.

Solution 4 - vb.net

OrElse evaluate first expression then if its true it will proceed to the statement while OR evaluates two expressions before it will proceed to their statement.

Example:

Textbox1.Text= 4

Textbox2.Text= ""

Using OrElse

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

Result is: TRUE


Using OR

 If TextBox1.Text > 2 Or TextBox2.Text > 3 Then

            MsgBox("True")
  End If

Result is: Error cannot convert string to double.

Solution 5 - vb.net

(I've looked at other answers and realized I was terribly wrong)

The OrElse operator "performs short-circuiting logical disjunction on two expressions", that is to say: if the left operand is true and so the entire expression is guaranteed to be true the right operand won't even be evaluated (this is useful in cases like:

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

to avoid a NullReferenceException throw by the right-hand operand.

I'm sincerely astonished that this (lazy evaluation) isn't the default behaviour of or and and as it is in C/C++ and C# (and many other languages...)

Solution 6 - vb.net

The Bert' s answer is not very accurate. The '|' or '&' is logical operator, in C #, it always treat as bit operator, please see the following code as example

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

The following is 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

when you use || to test "a == null" and "a.ToString() == "sdffd", the IL will be

 .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

Now you can see the difference, please don't think the '|' or 'and' as conditional operator, it just a logical operator, I don't think there is necessary to use it to judge condition

Solution 7 - vb.net

The reason the compilation fails in the example is the order of operations.

The expression parser is trying to evaluate "dbnull.value or temp" first.

if temp is (dbnull.value or temp) = 0

The error is here, because you can't do a bitwise OR between an integer (temp) and dbnull.value.

OrElse fixes this, not because it's short-circuited, but because it's lower on the order of operations, and so "temp is dbnull.value" and "3=0" are being evaluated first, rather than the parser trying to compare dbNull and temp.

So the evaluation with OrElse works like you're expecting: (assume temp=3)

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

This was actually on an entry exam at a software company I used to work for, and it was a common problem I used to encounter in VB6. So it's a good idea to parenthesize your sub-expressions when using boolean operators:

This would have compiled properly:

if (temp is dbnull.value) Or (temp = 0) then 

Although, as everyone has already pointed out, OrElse and AndAlso are really the correct operators to use in this context.

Solution 8 - vb.net

Unless your code logic requires the short-circuiting behavior OrElse provides, I would lean toward using the Or operator because:

  • Using "Or" is simple and requires less typing.
  • The computational time savings of using OrElse is negligible in most cases.
  • Most importantly, using OrElse can hide errors in later clauses that may not be initially revealed until those conditions would eventually be met by the program logic.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOrElseView Question on Stackoverflow
Solution 1 - vb.netAakashMView Answer on Stackoverflow
Solution 2 - vb.netBert HeesbeenView Answer on Stackoverflow
Solution 3 - vb.netstevehipwellView Answer on Stackoverflow
Solution 4 - vb.netLarzView Answer on Stackoverflow
Solution 5 - vb.netUtaalView Answer on Stackoverflow
Solution 6 - vb.netFrankXView Answer on Stackoverflow
Solution 7 - vb.netTomXP411View Answer on Stackoverflow
Solution 8 - vb.netKnowKnotView Answer on Stackoverflow