При срывании оценки оператора — это гарантируется? [C#]

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

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

//....
}

Гарантируется, что оценка остановится после "MyArray. Количество" часть, при условии, что часть верна? Иначе я получу пустую исключительную ситуацию во второй части.

16
задан Andrew Hare 22 April 2010 в 16:13
поделиться

5 ответов

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

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

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

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

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

  • Только условные операторы поддерживают короткое замыкание, логические - нет.
  • Логические операторы C # выглядят так же, как их условные аналоги, но с одним символом меньше, поэтому логическое ИЛИ - | , а логическое И - & .
  • Логические операторы могут быть перегружены, но условные операторы - нет (это небольшая техническая сторона, поскольку оценка условного оператора включает разрешение перегрузки, и это разрешение перегрузки может разрешаться в пользовательскую перегрузку логического оператора типа, поэтому вы можете обойти это ограничение до определенной степени).
34
ответ дан 30 November 2019 в 15:30
поделиться

Да, гарантируется.

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

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

12
ответ дан 30 November 2019 в 15:30
поделиться

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

Вы сказали следующее:

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

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

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

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

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

if (conditionHolds)
{
    //....
}
2
ответ дан 30 November 2019 в 15:30
поделиться

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

5
ответ дан 30 November 2019 в 15:30
поделиться

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

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

//.... 
} 

Это также гарантирует короткое замыкание.

-1
ответ дан 30 November 2019 в 15:30
поделиться
Другие вопросы по тегам:

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