Вопрос по c#, short-circuiting, logical-operators, conditional-operator – Оценка короткого замыкания - это гарантировано? [C #]

16

Быстрый вопрос здесь о коротких замыканиях в C #. С оператором if, как это:

if (MyObject.MyArray.Count == 0 || MyObject.MyArray[0].SomeValue == 0)
{

//....
}

Гарантируется ли, что оценка прекратится после части «MyArray.Count», при условии, что эта часть верна? В противном случае я получу нулевое исключение во второй части.

Если вы задаете этот вопрос, потому что высделал получить исключение нулевой ссылки из приведенного выше кода, скорее всего, потому чтоMyArray является нулевым илиMyArray[0] содержит ноль. Смотри мой ответ. Dan Tao

Ваш Ответ

6   ответов
2

Да,

Для операций AND, если какой-либо из операндов оценивается как false, тогда общее выражение оценивается как false, тогда нет необходимости оценивать оставшиеся выражения, а в случае операции OR, если какой-либо из операндов оценивается как true, тогда оставшаяся оценка может быть пропущена.

Таким образом, используя && или || Оператор, все выражение может быть оценено как истина или ложь без оценки всех подвыражений.

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

5

Да, это гарантировано, но вы все равно можете получить исключение нулевой ссылки, если MyArray имеет значение null (или MyObject в этом отношении, очевидно).

34

Да, это гарантировано.

Спецификация языка C # - 7.11 Условные логические операторы:

&& а также|| операторы называются условными логическими операторами.Их также называют «короткозамкнутыми» логическими операторами.

Поэтому они будут поддерживать логическое короткое замыканиепо определению - Вы можете положиться на это поведение.

Теперь важно провести различие междуусловный оператор илогический оператор:

  • Только условные операторы поддерживают короткое замыкание, логические операторы - нет.
  • Логические операторы C # выглядят так же, как их условные аналоги, но с одним символом меньше, поэтому логическое ИЛИ| и логическое И есть&.
  • Логические операторы могут быть перегружены, но условные операторы не могут (это немного технически, так как условная оценка оператора действительно включает разрешение перегрузки, и это разрешение перегрузки может разрешить пользовательскую перегрузку логического оператора типа, так что вы можете обойти это ограничение до определенной степени).
+1 за фактическое цитирование CLS. Polynomial
12

Да, это гарантировано.

http://msdn.microsoft.com/en-us/library/6373h346%28v=VS.80%29.aspx

Оператор условного ИЛИ (||) выполняет логическое ИЛИ своих булевых операндов, но только при необходимости оценивает свой второй операнд.

-1

Я предпочитаю использовать оператор &&, потому что тогда вы тестируете положительный результат (мой массив содержит элементы), а не отрицательный (моя ошибка не содержит элементов):

if (MyObject.MyArray.Count > 0 && MyObject.MyArray[0].SomeValue == 0) 
{ 

//.... 
} 

Это также гарантировано для короткого замыкания.

Результат этого кода не такой же, как у него. По его мнению, если счет равен 0, он замыкается и входит в блок. В твоем этотолько входит в блок по значению первого элемента, равному 0. Anthony Pegram
2

Просто небольшое наблюдение.

Вы сказали это:

В противном случае я получунулевое исключение во второй части. (подчеркивает мой)

На самом деле это не так. Если короткое замыкание не гарантировано, вы можете получитьIndexOutOfRangeException во второй части.

Этоеще возможно, вы могли бы получитьNullReferenceException, если первый элемент в вашемMyArray объект на самом деле является нулевым (или если любой изДругой объекты в этом выражении есть).

Единственныйполностью безопасная проверка будет такой:

bool conditionHolds =
    MyObject == null ||
    MyObject.MyArray == null ||
    MyObject.MyArray.Count == 0 ||
    MyObject.MyArray[0] == null ||
    MyObject.MyArray[0].SomeValue == 0;

if (conditionHolds)
{
    //....
}
Я думаю, что вы: if (! ConditionHolds) riffnl
@riffnl: Нет, я просто приводил свой пример в соответствие с кодом ОП. (Кажется, он / она хочет, чтобы код что-то делал в отрицательном случае.) Dan Tao

Похожие вопросы