В чем разница между or и OrElse ?
if temp is dbnull.value or temp = 0
выдает ошибку:
Оператор '=' не определен для типа DBNull и типа Integer.
а этот работает как шарм !?
if temp is dbnull.value OrElse temp = 0
OrElse
является короткозамкнутым оператором, Or
не является.
По определению логического оператора «или», если первый член истинен, тогда все определенно истинно, поэтому нам не нужно оценивать второй член.
OrElse
знает это, поэтому не пытается оценить, как temp = 0
только выяснится, чтоtemp Is DBNull.Value
Or
не знает этого и всегда будет пытаться оценить оба термина. Когда temp Is DBNull.Value
, его нельзя сравнивать с нулем, поэтому он падает.
Вы должны использовать ... ну, какой из них имеет смысл.
Это то же поведение, что и в C #, где все используют Coditional Or (||) и Условное And (&&), где у вас также есть нормальное Or (|) и нормальное And (&). Итак, сравнение C # с VB.Net:
| => Или
|| => OrElse
& => И
&& => И еще
Условные логические операторы очень полезны для предотвращения вложенных конструкций if. Но иногда необходимы обычные логические операторы, чтобы гарантировать попадание в оба пути кода.
источник
|
и&
в C # это побитовые операторы, а не логические операции вообще.OrElse закорочен , это означает, что только одна сторона выражения будет проверена, если первая сторона совпадает.
Так же, как AndAlso будет проверять только одну сторону выражения, если первая половина не удалась.
источник
(Я просмотрел другие ответы и понял, что ужасно ошибался)
Оператор OrElse «выполняет короткое логическое разделение двух выражений», то есть: если левый операнд истинен и поэтому все выражение гарантированно истинно, правый операнд даже не будет оцениваться (это полезно в случаи как:
string a; //... if (a is null) or (a = "Hi") //...
чтобы избежать выброса исключения NullReferenceException правым операндом.
Я искренне удивляло , что это ( ленивая оценка ) не является поведением по умолчанию
or
и ,and
как в C / C ++ и C # (и многие другие языки ...)источник
OrElse оценивает первое выражение, затем, если оно истинно, оно переходит к оператору, а OR оценивает два выражения, прежде чем перейти к их оператору.
Пример:
Textbox1.Text= 4 Textbox2.Text= ""
Использование OrElse
If TextBox1.Text > 2 OrElse TextBox2.Text > 3 Then MsgBox("True") End If
Результат: ИСТИНА
Использование OR
If TextBox1.Text > 2 Or TextBox2.Text > 3 Then MsgBox("True") End If
Результат: Ошибка не может преобразовать строку в двойную.
источник
Ответ Берта не очень точен. '|' или '&' является логическим оператором, в 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
Теперь вы видите разницу, пожалуйста, не думайте о "|" или 'и' как условный оператор, это просто логический оператор, я не думаю, что его нужно использовать для оценки условия
источник
The '|' or '&' is logical operator, in C #, it always treat as bit operator
. Я тоже верил в это, пока не увидел эту ссылку, msdn.microsoft.com/en-us/library/kxszd0kx.aspxЕсли ваша логика кода не требует поведения короткого замыкания, которое обеспечивает OrElse, я бы склонился к использованию оператора Or, потому что:
источник
Причина сбоя компиляции в этом примере - это порядок операций.
Синтаксический анализатор выражений сначала пытается вычислить "dbnull.value или temp".
if temp is (dbnull.value or temp) = 0
Ошибка здесь, потому что вы не можете выполнить побитовое ИЛИ между целым числом (temp) и dbnull.value.
OrElse исправляет это не потому, что он закорочен, а потому, что он ниже по порядку операций , и поэтому сначала оцениваются «temp is dbnull.value» и «3 = 0», а не анализатор, пытающийся сравнить dbNull и темп.
Таким образом, оценка с помощью 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 действительно являются правильными операторами для использования в этом контексте.
источник