program story

Or 대 OrElse

inputbox 2020. 9. 5. 09:53
반응형

Or 대 OrElse


orOrElse 의 차이점은 무엇입니까 ?

if temp is dbnull.value or temp = 0

오류를 생성합니다.

연산자 '='이 'DBNull'유형 및 'Integer'유형에 대해 정의되지 않았습니다.

이것은 매력처럼 작동하는 동안!?

if temp is dbnull.value OrElse temp = 0

OrElseA는 단락 오퍼레이터가 Or아니다.

부울 'or'연산자의 정의에 따라 첫 번째 항이 참이면 전체가 확실히 참입니다. 따라서 두 번째 항을 평가할 필요가 없습니다.

OrElse이 사실을 알고 있으므로 temp = 0일단 확인되면 평가하지 않습니다.temp Is DBNull.Value

Or이 사실을 모르고 항상 두 용어를 모두 평가하려고합니다. temp Is DBNull.Value이 제로 비교할 수없는, 그래서 이상 떨어진다.

당신은 ... 글쎄, 어느 쪽이든 말이되는 것을 사용해야합니다.


이것은 모두가 Coditional Or (||)와 Conditional And (&&)를 사용하는 C #과 동일한 동작입니다. 여기서 일반 Or (|)와 일반 And (&)도 있습니다. 따라서 C #을 VB.Net과 비교하는 것은 다음과 같습니다.

| => 또는

|| => OrElse

& => 그리고

&& => AndAlso

조건부 부울 연산자는 중첩 if 생성을 방지하는 데 매우 유용합니다. 그러나 때로는 두 코드 경로를 모두 맞추기 위해 일반 부울 연산자가 필요합니다.


OrElse는 단락 회로입니다 . 즉, 첫 번째면이 일치하는 경우 표현식의 한 면만 테스트됩니다.

AndAlso와 마찬가지로 전반부가 실패하면 표현식의 한쪽 만 테스트합니다.


(나는 다른 답변을 보았고 내가 몹시 틀렸다는 것을 깨달았습니다)

OrElse 연산자는 "두 식에 대해 단락 논리 분리를 수행합니다."즉, 왼쪽 피연산자가 참이고 전체식이 참이라고 보장하면 오른쪽 피연산자가 평가되지 않습니다. 다음과 같은 경우 :

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

오른쪽 피연산자에 의한 NullReferenceException throw를 방지합니다.

이 ( 게으른 평가 )가 기본 동작이 아니며 C / C ++ 및 C # (및 기타 여러 언어 ...)에서 orand같이 진심으로 놀랐 습니다.


OrElse는 첫 번째 식을 평가 한 다음 참이면 문으로 진행하고 OR는 두 식을 평가 한 후 문으로 진행합니다.

예:

Textbox1.Text= 4

Textbox2.Text= ""

OrElse 사용

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

결과 : TRUE


OR 사용

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

            MsgBox("True")
  End If

결과 : 오류는 문자열을 double로 변환 할 수 없습니다.


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


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.

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.

참고URL : https://stackoverflow.com/questions/1170754/or-versus-orelse

반응형