В чем разница между А и А также в VB.NET?

Ответы:

380

AndОператор оценивает обе стороны, где AndAlsoоценивает правая сторона , если и только если левая сторона истинна.

Пример:

If mystring IsNot Nothing And mystring.Contains("Foo") Then
  ' bla bla
End If

Выше выдает исключение, если mystring = Nothing

If mystring IsNot Nothing AndAlso mystring.Contains("Foo") Then
  ' bla bla
End If

Этот не исключение.

Так что, если вы пришли из мира C #, вы должны использовать, AndAlsoкак вы бы использовали &&.

Более подробная информация здесь: http://www.panopticoncentral.net/2003/08/18/the-ballad-of-andalso-and-orelse/

Нико
источник
2
Ссылка "Больше информации" не работает. Вот новый URL: panopticoncentral.net/2003/08/18/…
Рори О'Кейн
12
Кто-нибудь знает, почему они не выбрали вместо этого «AndThen»? Я думаю, что это было бы более интуитивно понятно.
Могучий
7
Я всегда думал, что это противоречит интуиции. И также подразумевал бы, что собирается проверить оба, и это должно быть наоборот! Следовательно, почему я должен приехать в SO, чтобы проверить такие вещи (да, я AC # парень). Вам также никогда не придется задавать вопрос типа «разница между А и А». Слишком много ands! Мой учитель английского убил бы меня
Робин Френч
3
Каждый раз, когда я пользуюсь OrElse, я всегда думаю о South Park "Или еще что?" «Точно»
Робин Френч
1
@ tmighty, предполагающий, что это вызовет больше путаницы, потому что Thenэто его собственное ключевое слово.
Бинки
29

AndОператор проверит все условия в заявлении , прежде чем продолжить, в то время как оператор AndAlso остановится , если он знает , что условие ложно. Например:

if x = 5 And y = 7

Проверяет, равен ли x 5, а если y равен 7, то продолжается, если оба значения верны.

if x = 5 AndAlso y = 7

Проверяет, равен ли x 5. Если это не так, он не проверяет, равен ли y 7, потому что он знает, что условие уже ложно. (Это называется коротким замыканием.)

Обычно люди используют метод короткого замыкания, если есть причина явно не проверять вторую часть, если первая часть не соответствует действительности, например, если она выбрасывает исключение, если проверено. Например:

If Not Object Is Nothing AndAlso Object.Load()

Если бы он использовался Andвместо AndAlso, он все равно попытался Object.Load()бы сделать это nothing, даже если бы это было так , что породило бы исключение.

Эд Марти
источник
14
Если у правой стороны есть побочный эффект, который вам нужен, просто переместите его в левую сторону, а не с помощью «И». Вам действительно нужно «И», если у обеих сторон есть побочные эффекты. И если у вас так много побочных эффектов, вы, вероятно, делаете что-то еще неправильно.
Джоэл Коухорн
1
Во-первых, Andalso в первую очередь не используется для «экономии времени выполнения», это нелепо. Во-вторых, наличие второго аргумента для выполнения некоторого полезного «побочного эффекта» - отвратительная плохая практика.
Тор Хауген
2
Вы не можете утверждать, что это не 'экономит на времени выполнения' все же. И я нашел ситуации, когда побочные эффекты на самом деле не плохая практика.
Эд Марти
1
«Обычно люди используют метод короткого замыкания , если есть причина явно не проверить вторую часть» ERM, ВТУ? Я надеюсь, что люди используют короткое замыкание, если у них нет причин не делать этого! Никто не должен использовать старые and/ orесли у них нет причин - из которых, я думаю, законных мало и далеко. Конечно, есть причина, по которой большинство других языков по умолчанию замыкаются: он сохраняет смысл результата, не оценивая потенциально дорогостоящие выражения, когда они ничего не вносят. Побочные эффекты в условиях должны быть, ну, в общем, побочными. Но это только мое мнение ...
underscore_d
20

Интересно, что ни в одном из ответов не упоминалось, что Andи Orв VB.NET есть битовые операторы, тогда как OrElseи AndAlsoявляются строго булевыми операторами.

Dim a = 3 OR 5 ' Will set a to the value 7, 011 or 101 = 111
Dim a = 3 And 5 ' Will set a to the value 1, 011 and 101 = 001
Dim b = 3 OrElse 5 ' Will set b to the value true and not evaluate the 5
Dim b = 3 AndAlso 5 ' Will set b to the value true after evaluating the 5
Dim c = 0 AndAlso 5 ' Will set c to the value false and not evaluate the 5

Примечание : считается ненулевое целое число true; Dim e = not 0Установим eдля -1демонстрации Notтакже немного оператора.

||и &&(версии C # OrElseи AndAlso) возвращают последнее оцененное выражение, которое будет 3и 5соответственно. Это позволяет вам использовать идиому v || 5в C #, чтобы дать 5в качестве значения выражения когда vis nullили ( 0и целое число) и значение vиначе. Разница в семантике может поймать программиста на C #, увлекающегося VB.NET врасплох, так как эта «идиома значения по умолчанию» не работает в VB.NET.

Итак, чтобы ответить на вопрос : используйте Orи Andдля битовых операций (целочисленные или логические). Используйте OrElseи AndAlsoдля «короткого замыкания» операции, чтобы сэкономить время, или проверить достоверность оценки до ее оценки. If valid(evaluation) andalso evaluation thenилиif not (unsafe(evaluation) orelse (not evaluation)) then

Бонус: какова ценность следующего?

Dim e = Not 0 And 3
Чарльз Джекс
источник
Я думаю, что вы перепутали ||и &&с ??. В то время как есть языки, которые ||будут возвращать не ложное значение, C # не является одним из них и возвращает a bool(за исключением поднятых обнуляемых операторов, где вы получаете Nullable<bool>результат)
Бен Фойгт
14
If Bool1 And Bool2 Then

Оценивает как Bool1 и Bool2

If Bool1 AndAlso Bool2 Then

Оценивает Bool2 тогда и только тогда, когда Bool1 имеет значение true.

Брайан Андерсон
источник
13

Просто для всех тех людей, которые говорят, что побочные эффекты являются злом: место, где наличие двух побочных эффектов в одном условии - это хорошо, будет читать два файловых объекта в тандеме.

While File1.Seek_Next_Row() And File2.Seek_Next_Row()
    Str1 = File1.GetRow()
    Str2 = File2.GetRow()
End While

Использование Andгарантирует, что строка используется каждый раз, когда проверяется условие. Принимая во внимание, что AndAlsoможет прочитать последнюю строку File1и оставить File2без использованной строки.

Конечно, приведенный выше код не будет работать, но я использую подобные побочные эффекты все время и не буду считать его « плохим » или « злым » кодом, как некоторые заставят вас поверить. Это легко читать и эффективно.

Ян
источник
5

Простой способ думать об этом - использовать еще более простой английский

If Bool1 And Bool2 Then
If [both are true] Then


If Bool1 AndAlso Bool2 Then
If [first is true then evaluate the second] Then
rbrill
источник
3
Английский язык более запутанный, чем код, потому что у него нет спецификации!
Бинки
5

And также очень похож на And, за исключением того, что он работает как && в C #, C ++ и т. Д.

Разница заключается в том, что если первое предложение (то, которое находится перед AndAlso) является истинным, второе предложение никогда не оценивается - составное логическое выражение является «короткозамкнутым».

Это иногда очень полезно, например, в выражении, таком как:

If Not IsNull(myObj) AndAlso myObj.SomeProperty = 3 Then
   ...
End If

Использование старого выражения And в вышеприведенном выражении вызовет исключение NullReferenceException, если myObj будет нулевым.

Тор Хауген
источник
5

Также см. Вопрос переполнения стека. Должен ли я всегда использовать операторы AndAlso и OrElse? ,

Также: Комментарий для тех, кто упомянул использование, Andесли правая сторона выражения имеет побочный эффект, который вам нужен:

Если у правой стороны есть побочный эффект, который вам нужен, просто переместите его в левую сторону, а не с помощью «И». Вам действительно нужно «И», если у обеих сторон есть побочные эффекты. И если у вас так много побочных эффектов, вы, вероятно, делаете что-то еще неправильно. В общем, вы действительно должны предпочесть AndAlso.

Джоэл Коухорн
источник
3

В дополнение к ответам выше, AndAlso также обеспечивает процесс кондиционирования, известный как короткое замыкание. Многие языки программирования имеют такую ​​встроенную функциональность, как и vb.net, и могут обеспечить существенное повышение производительности в длинных операторах условий, исключая ненужные оценки.

Другим аналогичным условием является условие OrElse, которое проверяет правильное условие только в том случае, если левое условие ложно, таким образом исключая ненужные проверки условий после обнаружения истинного условия.

Я бы посоветовал вам всегда использовать процессы короткого замыкания и структурировать ваши условные выражения так, чтобы это могло принести наибольшую пользу. Например, сначала проверьте свои самые эффективные и самые быстрые условия, чтобы длительные условия выполнялись только тогда, когда вам абсолютно необходимо, и короткое замыкание в другое время.

davidallyoung
источник
Также стоит упомянуть IIF (Immediate If), потому что он не замыкает накоротко и может создавать условия, совершенно не похожие на намерения программиста, поскольку оцениваются как истинные, так и ложные компоненты. Ранее кто-то заявлял, что он использует это побочное поведение преднамеренно, но - я не рассматриваю это как эффективный метод, поскольку Immediate If не имеет намеренного намерения проводить оценку таким образом, который я могу обнаружить.
Джинзай
«В дополнение к ответам выше, AndAlso также обеспечивает процесс кондиционирования, известный как короткое замыкание». Каждый ответ выше этого посвящен короткому замыканию. : P Но хорошее описание и рекомендации.
underscore_d
1

Для большинства из нас OrElse и AndAlso сделают свое дело, за исключением нескольких запутанных исключений (менее 1%, когда нам, возможно, придется использовать Or и And).

Постарайтесь не увлекаться людьми, которые хвастаются своей логической логикой и делают ее похожей на ракетостроение.

Это довольно просто и прямо, и иногда ваша система может работать не так, как ожидалось, потому что она не любит вашу логику в первую очередь. И все же ваш мозг постоянно говорит вам, что его логика на 100% проверена и доказана, и она должна работать. В этот самый момент перестаньте доверять своему мозгу и попросите его подумать еще раз, или (не OrElse или, возможно, OrElse) вы заставите себя искать другую работу, которая не требует большой логики.

Ананд
источник
0

Чтобы понять словами, а не тресками:

Вариант использования:
с «И» компилятор проверит все условия, поэтому, если вы проверяете, что объект может быть «Ничем», а затем вы проверяете одно из его свойств, у вас будет ошибка времени выполнения.
Но с AndAlso с первым «ложным» в условиях он будет проверять следующее, чтобы у вас не было ошибки.

Бэзил
источник