Какова лучшая практика в отношении оценки короткого замыкания в C #? - PullRequest
16 голосов
/ 12 декабря 2008

Ответ и последующие дебаты в комментариях в другой ветке побудили меня спросить:

В C # || и && - короткие версии логических операторов | и & соответственно.

Пример использования:

if (String.IsNullOrEmpty(text1) | String.IsNullOrEmpty(text2) | String.IsNullOrEmpty(text3))
{
    //...
}

против

if (String.IsNullOrEmpty(text1) || String.IsNullOrEmpty(text2) || String.IsNullOrEmpty(text3))
{
    //...
}

С точки зрения практики кодирования, что лучше использовать и почему?

Примечание: я понимаю, что этот вопрос похож на этот вопрос , но я считаю, что это требует обсуждения на конкретном языке.

Ответы [ 3 ]

45 голосов
/ 12 декабря 2008

С точки зрения практики кодирования, что лучше использовать и почему?

Простой ответ: всегда используйте закороченные версии. Там просто нет причин не делать этого. Кроме того, вы делаете свой код более понятным, потому что выражаете свое намерение : логическая оценка. Использование побитовых (логических) операций подразумевает, что вам нужно именно это: битовые операции, а не логическая оценка (хотя MSDN называет их также «логическими операторами», когда они применяются к логическим значениям).

Кроме того, поскольку короткое замыкание оценивает только то, что нужно оценить, оно часто быстрее и позволяет писать такой код как

bool nullorempty = str == null || str.Length == 0;

(Обратите внимание, что для решения этой конкретной проблемы уже существует лучшая функция, а именно string.IsNullOrEmpty, которую вы также использовали в своем вопросе.) Этот код был бы невозможен с побитовыми логическими операциями, потому что даже если бы str были null, второе выражение получило бы оценку, в результате чего NullReferenceException.

РЕДАКТИРОВАТЬ : Если вы хотите, чтобы побочные эффекты возникали в логическом контексте, пожалуйста, все же не используйте побитовые операции. Это типичный пример того, чтобы быть слишком умным. Следующий сопровождающий код (или даже вы сами, через несколько недель) увидит, что этот код будет думать: «Хм, этот код можно очистить, используя условные операторы», таким образом непреднамеренно нарушая код. Мне жаль того, кто отвечает за исправление этой ошибки.

Вместо этого, если вам приходится полагаться на побочные эффекты, сделайте их явными:

bool hasBuzzed = checkMakeBuzz();
bool isFrobbed = checkMakeFrob();
bool result = hasBuzzed || isFrobbed;

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

7 голосов
/ 12 декабря 2008

Я собираюсь ответить на этот вопрос в обратном порядке: когда только раз, когда я использую логические операторы?

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

bool isPasswordValid = true;

isPasswordValid &= isEightCharacters(password);
isPasswordValid &= containsNumeric(password);
isPasswordValid &= containsBothUppercaseAndLowercase(password);

return isPasswordValid;

На мой взгляд, вышесказанное более читабельно, чем:

return (isEightCharacters(password) &&
        containsNumberic(password)  &&
        containsBothUppercaseAndLowercase(password));

Недостатком является то, что это немного более эзотерично.

2 голосов
/ 12 декабря 2008

Используйте && и ||, если вы заботитесь только о результате и хотите знать этот результат как можно скорее, и ни одно из ваших выражений не имеет побочных эффектов, которые должны произойти, даже если логическое условие не выполнено. То есть почти всегда.

Используйте & и |, когда каждое выражение должно быть оценено (например, если у вас есть побочные эффекты от ваших выражений). Но поскольку у вас никогда не должно быть побочных эффектов, от которых зависит ваша программа, которые должны происходить, даже если логическое условие не выполняется, вам, вероятно, не следует использовать & и |.

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

if (false & somethingThatUpdatesTheDatabase()) { /* ... */ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...