2009-07-23 48 views
76

OrElse有什么区别?Or vs OrElse

if temp is dbnull.value or temp = 0 

产生错误:

Operator '=' is not defined for type 'DBNull' and type 'Integer'.

,而这一个工程就像一个魅力!?

if temp is dbnull.value OrElse temp = 0 

回答

114

OrElse短路运营商,Or不是。

通过布尔运算符的定义,如果第一项是真的,那么整体肯定是真的 - 所以我们不需要评估第二项。

OrElse知道这一点,所以不会尝试,一旦它确定了temp Is DBNull.Value

Or不知道这个评估temp = 0,并总是试图评估这两个术语。当temp Is DBNull.Value,它不能被比较为零,所以它翻倒。

你应该使用......好,无论哪一个是有道理的。

+2

所以或者只有当我在后面调用一个函数或有副作用时我的代码依赖? – 2009-07-23 10:09:07

+2

或者在所有第二个项目不会触发错误的情况下都是有意义的,如果第一个项目是真的... – awe 2009-07-23 10:16:35

4

(我看过其他的答案,并意识到我是可怕的错误)

的OrElse运算符“对两个表达式短路逻辑或”,即:如果左操作数的真实,所以整个表达保证是真右操作数甚至不会被评估(这是有用的像的情况下:

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

,以避免由右手操作数一个NullReferenceException掷

我真诚地惊讶,这(懒评价)不是or和默认行为and,因为它是在C/C++和C#(和许多其他语言...)

+7

事情是,在VB经典,有*只是*和和或,这是非短路。我认为**我说得对,VB.NET的第一个测试版实际上改变了这些运营商的行为 - 这引起了轩然大波,所以他们被改回来了,AndAlso和OrElse(短路)也被引入了。我只能想象他们必须考虑的替代名称,如果这些是最好的... – AakashM 2009-07-23 10:20:37

+1

通过提供Or和OrElse(|和||在C#中),这允许开发人员选择他们如何处理他们自己的代码。使用上面的代码,我不得不使用try catch来处理变量a中的空值。 OrElse允许开发人员在if语句的其他部分处理这一情况,作为已知的可能结果而不是例外情况。如果变量a是一个方法中的一个参数,那么对变量何时分配一个值(即,在方法之外) – 2012-03-22 14:54:29

8

OrElse是短路,这意味着如果第一条边匹配,则只会对表达式的一边进行测试。

就像AndAlso将只测试表达式的一边,如果前半部分是失败的。

33

这是相同的行为与C#,每个人都使用Coditional或(||)和有条件的(& &),在那里你也有正常的或(|),并在正常(&)。所以比较C#和VB。网为:

| =>或

|| => OrElse运算

& =>而

& & => AndAlso

的condifitonal布尔型的操作非常有用的,如果构造防止嵌套。但有时需要正常的布尔运算符来确保触发两个代码路径。

4

伯特的答案不是很准确。 '|'或“&”是逻辑运算符,在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 
当您使用

||测试“一== 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 

现在你可以看到其中的差别,请不要认为‘|’或'和'作为条件运算符,它只是一个逻辑运算符,我不认为有必要使用它来判断条件

2

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 

结果是:错误不能转换串翻一番。