[vb.net] 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로 변환 할 수 없습니다.


답변

Bert의 대답은 그다지 정확하지 않습니다. ‘|’ 또는 ‘&’는 논리 연산자입니다. C #에서는 항상 비트 연산자로 취급합니다. 다음 코드를 예제로 참조하십시오.

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

다음은 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

사용할 때 || “a == null”및 “a.ToString () ==”sdffd “를 테스트하려면 IL은

 .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

이제 차이를 볼 수 있습니다. ‘|’를 생각하지 마십시오. 또는 ‘and’조건부 연산자로 논리 연산자 일뿐입니다. 조건을 판단하는 데 사용할 필요는 없다고 생각합니다.


답변

코드 논리에 OrElse가 제공하는 단락 동작이 필요하지 않는 한 다음과 같은 이유로 Or 연산자를 사용합니다.

  • “Or”를 사용하는 것은 간단하며 입력이 덜 필요합니다.
  • OrElse 사용으로 인한 계산 시간 절약은 대부분의 경우 무시할 수 있습니다.
  • 가장 중요한 것은 OrElse를 사용하면 나중에 프로그램 논리에 의해 이러한 조건이 충족 될 때까지 처음에 공개되지 않을 수있는 이후 절의 오류를 숨길 수 있다는 것입니다.