或与 OrElse 之间的区别是什么?
if temp is dbnull.value or temp = 0
产生错误:
没有为类型'DBNull'定义Operator'='并输入'Integer'。
虽然这个就像魅力一样!?
if temp is dbnull.value OrElse temp = 0
答案 0 :(得分:130)
OrElse
是短路运算符,Or
不是。
通过布尔'或'运算符的定义,如果第一项是True,那么整体肯定是正确的 - 所以我们不需要评估第二项。
OrElse
知道这一点,因此一旦确定temp = 0
temp Is DBNull.Value
Or
不知道这一点,并且总是会尝试评估这两个字词。当temp Is DBNull.Value
时,它无法与零进行比较,因此会失败。
你应该使用......好吧,无论哪个都有意义。
答案 1 :(得分:38)
这与C#的行为相同,其中每个人都使用Coditional Or(||)和Conditional And(&&),其中你也有正常的Or(|)和正常的和(&) 。所以将C#与VB.Net进行比较是:
| =>或
|| => OrElse运算
&安培; =>和
&安培;&安培; => AndAlso
condifitonal布尔运算符非常有用,可以防止嵌套if构造。但有时需要普通的布尔运算符来确保命中两个代码路径。
答案 2 :(得分:8)
OrElse 短路,这意味着如果第一面匹配,则只会测试表达式的一侧。
就像AndAlso只测试表达式的一侧,如果前半部分是失败的话。
答案 3 :(得分:4)
(我看了其他答案并意识到我非常错误)
OrElse运算符“对两个表达式执行短路逻辑析取”,也就是说:如果左操作数为真,因此保证整个表达式为真,则不会对右操作数进行求值(这在以下情况下很有用:
string a;
//...
if (a is null) or (a = "Hi") //...
避免右手操作数抛出NullReferenceException。
我真的很惊讶这个( lazy evaluation )不是or
和and
的默认行为,因为它在C / C ++中C#(以及许多其他语言......)
答案 4 :(得分:4)
OrElse计算第一个表达式,然后判断它是否为真,它将继续执行语句,而OR在计算两个表达式之前将继续执行它们的语句。
示例:强>
@if($book->name == $file['basename'])
<p>Book</p>
@endif
使用OrElse
Textbox1.Text= 4
Textbox2.Text= ""
结果是: TRUE
使用OR
If TextBox1.Text > 2 OrElse TextBox2.Text > 3 Then
MsgBox("True")
End If
结果是:错误无法将字符串转换为double。
答案 5 :(得分:3)
Bert的回答并不准确。 '|'或'&amp;'是逻辑运算符,在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
现在你可以看到差异,请不要认为'|'或'和'作为条件运算符,它只是一个逻辑运算符,我认为没有必要用它来判断条件
答案 6 :(得分:0)
除非您的代码逻辑需要OrElse提供的短路行为,否则我倾向于使用Or运算符,因为:
答案 7 :(得分:0)
示例中编译失败的原因是操作顺序。
表达式解析器尝试首先评估“ dbnull.value或temp”。
if temp is (dbnull.value or temp) = 0
错误在这里,因为您不能在整数(temp)和dbnull.value之间进行按位或运算。
OrElse解决了此问题,不是因为它短路,而是因为它在操作顺序上比低,因此首先评估“ temp is dbnull.value”和“ 3 = 0” ,而不是解析器尝试比较dbNull和temp。
因此,使用OrElse进行评估的过程与您期望的一样:(假设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
这实际上是我曾经工作过的一家软件公司的入学考试,这是我以前在VB6中遇到的一个常见问题。因此,在使用布尔运算符时,最好将子表达式括起来:
这本来可以正确编译的:
if (temp is dbnull.value) Or (temp = 0) then
尽管,正如大家已经指出的那样,OrElse和AndAlso实际上是在这种情况下使用的正确运算符。