vb.net Or 与 OrElse

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1170754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 14:18:59  来源:igfitidea点击:

Or versus OrElse

vb.net

提问by OrElse

What's the difference between orand OrElse?

什么之间的区别还是OrElse运算

if temp is dbnull.value or temp = 0

produces the error:

产生错误:

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

运算符 '=' 未为类型 'DBNull' 和类型 'Integer' 定义。

while this one works like a charm!?

而这个就像一个魅力!?

if temp is dbnull.value OrElse temp = 0

回答by AakashM

OrElseis a short-circuitingoperator, Oris not.

OrElse短路运算符,Or不是。

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.

根据布尔“或”运算符的定义,如果第一项为真,则整体肯定为真——因此我们不需要评估第二项。

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

OrElse知道这一点,所以temp = 0一旦确定,就不要尝试和评估temp Is DBNull.Value

Ordoesn'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.

Or不知道这一点,并且将始终尝试评估这两个术语。当 时temp Is DBNull.Value,它不能与零比较,所以它会倒下。

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

你应该使用......好吧,无论哪个都有意义。

回答by Bert Heesbeen

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:

这与 C# 的行为相同,每个人都使用条件或 (||) 和条件与 (&&),其中也有普通的或 (|) 和普通的与 (&)。因此,将 C# 与 VB.Net 进行比较是:

| => 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.

条件布尔运算符对于防止嵌套 if 结构非常有用。但有时需要普通的布尔运算符来确保命中两个代码路径。

回答by stevehipwell

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

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

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

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

回答by Larz

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.

OrElse 评估第一个表达式,然后如果它为真,它将继续执行该语句,而 OR 在继续执行它们的语句之前评估两个表达式。

Example:

例子:

Textbox1.Text= 4

Textbox2.Text= ""

Using OrElse

使用 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.

结果是:错误无法将字符串转换为双精度。

回答by Utaal

(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:

OrElse 运算符“对两个表达式执行短路逻辑析取”,也就是说:如果左操作数为真并且整个表达式保证为真,则右操作数甚至不会被评估(这在以下情况下很有用)像这样的情况:

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

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

避免右侧操作数抛出 NullReferenceException。

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

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

回答by FrankX

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

伯特的回答不是很准确。'|' 或者'&'是逻辑运算符,在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();
        }

The following is IL

以下是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
 .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
if temp is (dbnull.value or temp) = 0
00) 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
00) 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

当你使用 || 要测试“a == null”和“a.ToString() ==”sdffd”,IL 将是

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

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

现在你可以看到区别了,请不要认为'|' or 'and' 作为条件运算符,它只是一个逻辑运算符,我认为没有必要用它来判断条件

回答by KnowKnot

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

除非您的代码逻辑需要 OrElse 提供的短路行为,否则我倾向于使用 Or 运算符,因为:

  • 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.
  • 使用“或”很简单,需要的输入更少。
  • 在大多数情况下,使用 OrElse 节省的计算时间可以忽略不计。
  • 最重要的是,使用 OrElse 可以隐藏后面子句中的错误,这些错误最初可能不会在程序逻辑最终满足这些条件之前显示出来。

回答by TomXP411

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.

表达式解析器首先尝试评估“dbnull.value 或 temp”。

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

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

错误就在这里,因为您不能在整数 (temp) 和 dbnull.value 之间进行按位 OR。

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.

OrElse 解决了这个问题,不是因为它短路了,而是因为它在操作顺序较低,因此首先评估“temp 是 dbnull.value”和“3=0”,而不是解析器尝试比较 dbNull 和温度。

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

所以使用 OrElse 的评估就像你期望的那样:(假设 temp=3)

##代码##

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:

这实际上是在我以前工作的一家软件公司的入学考试中,这是我曾经在 VB6 中遇到的一个常见问题。因此,在使用布尔运算符时将子表达式括起来是个好主意:

This would have compiled properly:

这将正确编译:

##代码##

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

尽管正如每个人已经指出的那样,OrElse 和 AndAlso 确实是在这种情况下使用的正确运算符。